--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/viewframework/views/zoomview/src/glxzoomeventhandler.cpp Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,1227 @@
+/*
+* Copyright (c) 2008-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: Implementation of Zoom Event Handler
+*
+*/
+
+
+// Avkon
+#include <eikon.hrh>
+
+// Antariksh
+#include <alf/alfutil.h> // AlfUtil
+#include <mul/mulevent.h> // For Slider events
+
+//Photos Headers
+#include <glxtracer.h> // For Tracer
+#include <glxlog.h> // For Log
+
+#include <mglxuicommandhandler.h> // For MGlxUiCommandHandler
+#include <glxzoomeventhandler.h>
+#include <glxzoommathsengine.h>
+#include <glxzoomcontrol.h>
+#include <glxzoomeventhandler.h>
+
+
+// LOCAL CONSTANTS AND MACROS
+const TInt KTimerLengthInMicroseconds = 100000 ;
+const TInt KGlxScreenTimeout = 2000000 ; // 2 seconds timer for UI On/Off
+
+const TInt KGlxAnimationTimeDrag = 30 ;
+const TInt KGlxAnimationTimekeyPan = 50 ;
+
+const TInt KGlxZoomPanInc = 5 ; // Min number of pixels panned in one keypress. This value is incremented exponentially by multiples of iPanFactor
+
+// Anime Speed changes in inverse proportion to KGlxAnimeFrameInmS.
+// Steps increase with KGlxAnimeFrameCount.
+// Total time taken = (KGlxAnimeFrameInmS * KGlxAnimeFrameCount)microseconds.
+const TInt KGlxAnimeFrameInmS = 10000 ;
+const TInt KGlxAnimeFrameCount = 10 ;
+
+const TInt KGlxPanInertiaFrameInmS = 20000 ;
+
+using namespace GestureHelper;
+
+// ============================ CGlxZoomPanEventHandler===============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+//----------------------------------------------------------------------------------
+// NewL
+//----------------------------------------------------------------------------------
+//
+CGlxZoomPanEventHandler* CGlxZoomPanEventHandler::NewL(MGlxZoomEventHandlers& aZoomEventHandler)
+ {
+ TRACER("CGlxZoomPanEventHandler::NewL");
+ CGlxZoomPanEventHandler* self = new (ELeave) CGlxZoomPanEventHandler(aZoomEventHandler);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+//----------------------------------------------------------------------------------
+// CGlxZoomPanEventHandler constructor
+//----------------------------------------------------------------------------------
+//
+CGlxZoomPanEventHandler::CGlxZoomPanEventHandler(MGlxZoomEventHandlers& aZoomEventHandler):
+ iZoomEventHandler(aZoomEventHandler)
+ {
+ TRACER("CGlxZoomPanEventHandler::CGlxZoomPanEventHandler()");
+ // No Implementation
+ }
+
+//----------------------------------------------------------------------------------
+// CGlxZoomPanEventHandlerDestructor
+//----------------------------------------------------------------------------------
+//
+CGlxZoomPanEventHandler::~CGlxZoomPanEventHandler()
+ {
+ TRACER("CGlxZoomPanEventHandler::~CGlxZoomPanEventHandler()");
+ if(iZoomPanTimer)
+ {
+ CancelZoomPanTimer();
+ delete iZoomPanTimer;
+ iZoomPanTimer = NULL;
+ }
+ if (iUiTimer)
+ {
+ CancelUITimer();
+ delete iUiTimer;
+ iUiTimer = NULL;
+ }
+ if(iZoomAnimationTimer)
+ {
+ CancelAnimationTimer();
+ delete iZoomAnimationTimer;
+ iZoomAnimationTimer = NULL;
+ }
+
+ }
+
+//----------------------------------------------------------------------------------
+// CGlxZoomPanEventHandler Constructl
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::ConstructL()
+ {
+ TRACER("CGlxZoomPanEventHandler::ConstructL()");
+ if(!iUiTimer)
+ {
+ iUiTimer = CPeriodic::NewL(EPriorityNormal);
+ }
+ if(!iZoomPanTimer)
+ {
+ iZoomPanTimer = CPeriodic::NewL(EPriorityNormal);
+ }
+ if(!iZoomAnimationTimer)
+ {
+ iZoomAnimationTimer = CPeriodic::NewL(EPriorityNormal);
+ }
+ }
+
+//----------------------------------------------------------------------------------
+// CGlxZoomPanEventHandler SetupAnimatedZoom
+//----------------------------------------------------------------------------------
+//
+// Todo: Combine logics of setting up animated zoom and pan.
+void CGlxZoomPanEventHandler::SetupAnimatedZoom(TZoomMode aZoomMode, TPoint* aZoomFocus)
+ {
+ TRACER("CGlxZoomPanEventHandler::SetupAnimatedZoom");
+
+ iTargetAnimatedZoomRatio = (iMaxZoomRatio + iMinZoomRatio)/2 ;
+
+ CancelAnimationTimer();
+
+ //ToDo: Verify this with images slightly smaller or slightly larger than fullscreen size.
+ if (EZoomIn == aZoomMode)
+ {
+ // the '1+' is to take care of the situation when there the rest of the equation returns something betn 0 and 1
+ iZoomPerInterval = 1 + (iTargetAnimatedZoomRatio - iZoomRatio)/KGlxAnimeFrameCount ;
+ }
+ else
+ {
+ iZoomPerInterval = 1 + (iZoomRatio - iMinZoomRatio)/KGlxAnimeFrameCount;
+ }
+
+
+ if (1 < iZoomPerInterval)
+ {
+ iIsZoomingInAnimatedState = ETrue;
+
+ switch(aZoomMode)
+ {
+ case EZoomIn:
+ iAnimatedZoomMode = EAnimationModeZoomIn;
+ break;
+ case EZoomOut:
+ iAnimatedZoomMode = EAnimationModeZoomOut;
+ break;
+ }
+
+ iZoomAnimationTimer->Start( 0,
+ KGlxAnimeFrameInmS,
+ TCallBack( ActivationIntervalElapsed,(TAny*)this) );
+ }
+ else
+ // Cant zoom in/out at less than 1 percent. so directly jump to the target zoom ratio.
+ // This happens in cases where there is not much difference between the source and target zoom levels
+ {
+ TInt targetZoomRatio = 0;
+ if (EZoomIn == aZoomMode)
+ {
+ targetZoomRatio = iTargetAnimatedZoomRatio ;
+ }
+ else
+ {
+ targetZoomRatio = iMinZoomRatio ;
+ }
+ Zoom(targetZoomRatio, 0) ;
+ }
+ }
+
+//----------------------------------------------------------------------------------
+// CGlxZoomPanEventHandler ActivationIntervalElapsed
+//----------------------------------------------------------------------------------
+//
+TInt CGlxZoomPanEventHandler::ActivationIntervalElapsed(TAny* aPtr)
+ {
+ TRACER("CGlxZoomPanEventHandler::ActivationIntervalElapsed");
+
+ CGlxZoomPanEventHandler* self = static_cast<CGlxZoomPanEventHandler*>(aPtr);
+
+ self->NextStepAnimatedZoom();
+ return 0;
+ }
+
+//----------------------------------------------------------------------------------
+// CGlxZoomPanEventHandler NextStepAmimatedZoom
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::NextStepAnimatedZoom()
+ {
+ TRACER("CGlxZoomPanEventHandler::NextStepAmimatedZoom");
+
+ TInt targetZoomLevel = 0 ;
+
+ if (EAnimationModeZoomIn == iAnimatedZoomMode)
+ {
+ targetZoomLevel = iZoomRatio + iZoomPerInterval;
+ }
+ else
+ {
+ targetZoomLevel = iZoomRatio - iZoomPerInterval;
+ }
+
+ Zoom(targetZoomLevel, 0, EZoomIn, &iZoomFocus );
+
+ // The boundary conditions.
+ if ( (( targetZoomLevel >= iTargetAnimatedZoomRatio ) && (EAnimationModeZoomIn == iAnimatedZoomMode ) )
+ || ((targetZoomLevel <= iMinZoomRatio) && (EAnimationModeZoomOut == iAnimatedZoomMode)))
+ {
+ iIsZoomingInAnimatedState = EFalse;
+ CancelAnimationTimer();
+ TSize screensize = iMathsEngine.ScreenSize();
+ iZoomFocus = TPoint(screensize.iWidth>>1,screensize.iHeight>>1) ;
+ }
+ }
+
+
+//----------------------------------------------------------------------------------
+// StartZoomTimer:Starts the Zoom timer for continous zoom
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::StartZoomTimer()
+ {
+ TRACER("CGlxZoomPanEventHandler::StartZoomTimer");
+
+ if (iZoomPanTimer->IsActive())
+ {
+ iZoomPanTimer->Cancel();
+ }
+ iZoomPanTimer->Start( KTimerLengthInMicroseconds,
+ KTimerLengthInMicroseconds,
+ TCallBack( ZoomIntervalExpired,(TAny*)this) );
+ }
+
+//----------------------------------------------------------------------------------
+// StartPanTimer:Starts the Pan timer for continous Panning
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::StartPanTimer()
+ {
+ TRACER("CGlxZoomPanEventHandler::StartPanTimer ");
+
+ //After Panning in one direction for a long time by holding the key and
+ //then if panning is started in another direction,the panning will be done in more pixels.
+ iPanTime.HomeTime();
+
+ GLX_LOG_INFO("CGlxZoomPanEventHandler::StartPanTimer: Cancelling timers ");
+
+ if (iZoomPanTimer->IsActive())
+ {
+ iZoomPanTimer->Cancel();
+ }
+ iZoomPanTimer->Start( 0,
+ KTimerLengthInMicroseconds,
+ TCallBack( PanIntervalExpired,(TAny*)this) );
+
+ }
+
+//----------------------------------------------------------------------------------
+// CancelZoomPanTimer: Cancels the Zoom timer for continous zoom
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::CancelZoomPanTimer()
+ {
+ TRACER("CGlxZoomPanEventHandler::CancelZoomPanTimer ");
+
+ if (iZoomPanTimer->IsActive())
+ {
+ iZoomPanTimer->Cancel();
+ }
+ }
+
+//----------------------------------------------------------------------------------
+// CancelUITimer
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::CancelUITimer()
+ {
+ TRACER("CGlxZoomPanEventHandler::CancelUITimer ");
+
+ if (iUiTimer->IsActive())
+ {
+ iUiTimer->Cancel();
+ }
+ }
+
+//----------------------------------------------------------------------------------
+// CancelUITimer
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::CancelAnimationTimer()
+ {
+ TRACER("CGlxZoomPanEventHandler::CancelAnimationTimer ");
+
+ // This will set the timer to false if it is being used for zoom. For Pan
+ // this flag is immaterial
+ iIsZoomingInAnimatedState = EFalse;
+ if (iZoomAnimationTimer->IsActive())
+ {
+ iZoomAnimationTimer->Cancel();
+ }
+ }
+
+//----------------------------------------------------------------------------------
+// StartUITimer
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::StartUITimer(TTimeIntervalMicroSeconds32 aDelay,
+ TTimeIntervalMicroSeconds32 anInterval,
+ TCallBack aCallBack)
+ {
+ TRACER("CGlxZoomPanEventHandler::StartUITimer ");
+
+ if (iUiTimer->IsActive())
+ {
+ iUiTimer->Cancel();
+ }
+ iUiTimer->Start(aDelay,anInterval,aCallBack);
+ }
+
+// -----------------------------------------------------------------------------
+// HandlekeyEvents:This function handles the key Events.
+// -----------------------------------------------------------------------------
+//
+TBool CGlxZoomPanEventHandler::HandlekeyEvents(const TAlfEvent &aEvent)
+ {
+ TRACER("CGlxZoomControl::HandlekeyEvents()");
+ GLX_LOG_INFO1("CGlxZoomPanEventHandler::HandlekeyEvents. Scancode = %d ", aEvent.KeyEvent().iScanCode);
+
+ TBool consumed = EFalse;
+
+ if (!iIsZoomingInAnimatedState)
+ {
+ switch (aEvent.KeyEvent().iScanCode)
+ {
+ case EStdKeyDevice10: //Listen to EStdKeyDevice10 as EKeyLeftUpArrow key is mapped to TKeyCode::EKeyDevice10 for which TStdScancode is EStdKeyDevice10
+ case EKeyLeftUpArrow :
+ case EStdKeyDevice13: //Listen to EStdKeyDevice13 as EKeyLeftDownArrow key is mapped to TKeyCode::EKeyDevice13 for which TStdScancode is EStdKeyDevice13
+ case EKeyLeftDownArrow :
+ case EStdKeyDevice11://Listen to EStdKeyDevice11 as EKeyRightUpArrow key is mapped to TKeyCode::EKeyDevice11 for which TStdScancode is EStdKeyDevice11
+ case EKeyRightUpArrow :
+ case EStdKeyDevice12: //Listen to EStdKeyDevice12 as EKeyRightDownArrow key is mapped to TKeyCode::EKeyDevice12 for which TStdScancode is EStdKeyDevice12
+ case EKeyRightDownArrow :
+ case EStdKeyLeftArrow :
+ case EStdKeyRightArrow :
+ case EStdKeyUpArrow :
+ case EStdKeyDownArrow :
+ {
+ HandlePanKey(aEvent);
+ consumed = ETrue;
+ }
+ break;
+ case EStdKeyDevice0:
+ case EStdKeyDevice1:
+ case EStdKeyDevice3:
+ {
+ //Center button/MSK changes the UI State
+ if (aEvent.Code() == EEventKeyDown)
+ {
+ if (EUiOff == iZoomUiState )
+ {
+ ShowScreenFurniture(KGlxScreenTimeout);
+ }
+ else
+ {
+ HideScreenFurniture();
+ }
+ }
+ consumed = ETrue;
+ }
+ break;
+
+ //Listen EStdKeyApplicationC as EKeyZoomIn key is mapped to TKeyCode:: EKeyApplicationC for which TStdScancode is EStdKeyApplicatoinC
+ case EStdKeyApplicationC :
+ {
+ HandleZoomStripeAction(EZoomIn ,aEvent.Code()) ;
+ consumed = ETrue;
+ break ;
+ }
+ //Listen EStdKeyApplicationD as EKeyZoomOut key is mapped to TKeyCode:: EKeyApplicationD for which TStdScancode is EStdKeyApplicatoinD
+ case EStdKeyApplicationD :
+ {
+ HandleZoomStripeAction(EZoomOut,aEvent.Code());
+ consumed = ETrue;
+ break ;
+ }
+ case EStdKeyIncVolume :
+ case EKeyZoomIn :
+ case EStdKeyNkpAsterisk :
+ {
+ GLX_LOG_INFO1("CGlxZoomControl::HandlekeyEvents VLUP=%d", aEvent.KeyEvent().iScanCode );
+ if (iZoomActivated)
+ {
+ HandleZoomKey(EZoomIn, aEvent.Code());
+ }
+ consumed = ETrue;
+ break;
+ }
+ case EStdKeyDecVolume :
+ case EKeyZoomOut :
+ case EStdKeyHash :
+ {
+ GLX_LOG_INFO1("CGlxZoomControl::HandlekeyEvents VLUP_D=%d", aEvent.KeyEvent().iScanCode );
+ HandleZoomKey(EZoomOut, aEvent.Code());
+ consumed = ETrue;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return consumed;
+ }
+
+// -----------------------------------------------------------------------------
+// HandleZoomKey:Starts the Timer for contionous zoom
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HandleZoomKey(TZoomMode aZoomMode ,const TEventCode aEventCode )
+ {
+ TRACER("CGlxZoomControl::HandleZoomKey ");
+
+ if ( EEventKeyDown == aEventCode )
+ {
+ CancelUITimer();
+ iZoomEventHandler.HandleShowUi(ETrue);
+ iZoomMode = aZoomMode ;
+ StartZoomTimer();
+ }
+ else if ( EEventKeyUp == aEventCode )
+ {
+ CancelZoomPanTimer();
+ StartUITimer(KGlxScreenTimeout,KGlxScreenTimeout,TCallBack(
+ UiTimeOut,this )) ;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// HandleZoomStripeAction:Zooms the image on zoom stripe action.
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HandleZoomStripeAction(TZoomMode aZoomMode ,
+ TEventCode aEventCode)
+ {
+ TRACER("CGlxZoomControl::HandleZoomStripeAction ");
+ if ( iZoomActivated )
+ {
+ switch(aEventCode)
+ {
+ case EEventKey :
+ {
+ iZoomMode = aZoomMode ;
+ Zoom(0, 0, aZoomMode) ;
+
+ ShowScreenFurniture(KGlxScreenTimeout);
+ break ;
+ }
+ default :
+ break ;
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// SetupPanOperation: start the pan operation for Key based pan.
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::SetupPanOperation(TPoint& aPanDirection)
+ {
+ TRACER("CGlxZoomPanEventHandler::SetupPanOperation ");
+
+ iPanDirection = TPoint(aPanDirection);
+ if(EUiOn == iZoomUiState )
+ {
+ HideScreenFurniture();
+ }
+
+ StartPanTimer();
+
+ iMathsEngine.SetupPanOperation();
+ }
+
+// -----------------------------------------------------------------------------
+// HandlePanKey :handles the keys related to pan and starts the pan Timer
+// -----------------------------------------------------------------------------
+//
+TBool CGlxZoomPanEventHandler::HandlePanKey( const TAlfEvent &aEvent )
+ {
+ TRACER("CGlxZoomPanEventHandler::HandlePanKey ");
+
+ TSize imageVirtualSize = iMathsEngine.ImageVirtualSize();
+ TSize screenSize = iMathsEngine.ScreenSize();
+ TBool safeToPan = EFalse ;
+ TPoint panDirection(0,0);
+ TBool handled = EFalse;
+
+ if ( aEvent.Code() == EEventKeyDown )
+ {
+ //if height and/or width of the zoomed image is greater than the screen height and screen width ,
+ //then this paning should be posssible
+ switch(aEvent.KeyEvent().iScanCode )
+ {
+ case EStdKeyDevice10:
+ case EKeyLeftUpArrow:
+ {
+ if ((imageVirtualSize.iHeight>screenSize.iHeight)
+ &&(imageVirtualSize.iWidth > screenSize.iWidth))
+ {
+ safeToPan = ETrue;
+ panDirection = TPoint(-KGlxZoomPanInc, -KGlxZoomPanInc);
+ }
+ }
+ break;
+ case EStdKeyDevice11:
+ case EKeyRightUpArrow:
+ {
+ if ((imageVirtualSize.iHeight>screenSize.iHeight)
+ &&(imageVirtualSize.iWidth > screenSize.iWidth))
+ {
+ safeToPan = ETrue;
+ panDirection = TPoint(KGlxZoomPanInc, -KGlxZoomPanInc);
+ }
+ }
+ break;
+ case EStdKeyDevice12:
+ case EKeyLeftDownArrow:
+ {
+ if ((imageVirtualSize.iHeight>screenSize.iHeight)
+ &&(imageVirtualSize.iWidth > screenSize.iWidth))
+ {
+ safeToPan = ETrue;
+ panDirection = TPoint(-KGlxZoomPanInc, KGlxZoomPanInc);
+ }
+ }
+ break;
+ case EStdKeyDevice13:
+ case EKeyRightDownArrow:
+ {
+ if ((imageVirtualSize.iHeight>screenSize.iHeight)
+ &&(imageVirtualSize.iWidth > screenSize.iWidth))
+ {
+ safeToPan = ETrue;
+ panDirection = TPoint(KGlxZoomPanInc, KGlxZoomPanInc);
+ }
+ }
+ break;
+ case EStdKeyUpArrow:
+ {
+ if( (imageVirtualSize.iHeight ) > screenSize.iHeight )
+ {
+ safeToPan = ETrue;
+ panDirection = TPoint(0, -KGlxZoomPanInc);
+ }
+ }
+ break;
+ case EStdKeyDownArrow:
+ {
+ if( (imageVirtualSize.iHeight ) > screenSize.iHeight )
+ {
+ safeToPan = ETrue;
+ panDirection = TPoint(0, KGlxZoomPanInc);
+ }
+ }
+ break;
+ case EStdKeyLeftArrow:
+ {
+ if( (imageVirtualSize.iWidth ) > screenSize.iWidth )
+ {
+ safeToPan = ETrue;
+ panDirection = TPoint(-KGlxZoomPanInc, 0);
+ }
+ }
+ break;
+ case EStdKeyRightArrow:
+ {
+ if ((imageVirtualSize.iWidth ) > screenSize.iWidth )
+ {
+ safeToPan = ETrue;
+ panDirection = TPoint(KGlxZoomPanInc, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (safeToPan)
+ {
+ SetupPanOperation(panDirection);
+ handled = ETrue;
+ }
+ }
+ else if ( aEvent.Code() == EEventKeyUp)
+ {
+ // destroy the Pan infrastructure
+ // Reset the PanDirection and cancel the pan timers.
+ CancelZoomPanTimer();
+ iPanDirection = TPoint(0, 0);
+ handled = ETrue;
+ }
+ return handled;
+ }
+
+
+// -----------------------------------------------------------------------------
+// HandleDragEvent
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HandleDragEvent(const GestureHelper::MGestureEvent& aEvent )
+ {
+ TRACER("CGlxZoomControl::HandleDragEvent (GestureHelper::MGestureEvent&)");
+
+
+ // Ignore events when we are animating in Zoom
+ if (iIsZoomingInAnimatedState)
+ {
+ return;
+ }
+
+ TPoint startPos = aEvent.StartPos();
+ TPoint currPos = aEvent.CurrentPos();
+
+
+ // This means a new gesture has just started.
+ if (startPos != iPreviousDragStartPosition)
+ {
+ iPreviousPointerPosition = startPos;
+ }
+
+ TPoint offset((iPreviousPointerPosition.iX - currPos.iX) , (iPreviousPointerPosition.iY - currPos.iY));
+
+ HideScreenFurniture();
+
+ TPoint topLeftCorner(0,0);
+ iMathsEngine.Pan(offset, topLeftCorner, EGlxPanIncrementUniform);
+
+
+ iZoomEventHandler.HandleViewPortParametersChanged(topLeftCorner, KGlxAnimationTimeDrag);
+
+ iPreviousPointerPosition = currPos ;
+ iPreviousDragStartPosition = startPos;
+ }
+
+// -----------------------------------------------------------------------------
+// HandleGestureReleased
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HandleGestureReleased(const GestureHelper::MGestureEvent& aEvent )
+ {
+ TRACER("CGlxZoomPanEventHandler::HandleGestureReleasedEvent(const GestureHelper::MGestureEvent& )");
+
+ if ( /*(EGestureUnknown == iPreviousGestureCode)
+ ||*/(EGestureSwipeLeft == iPreviousGestureCode)
+ ||(EGestureSwipeRight == iPreviousGestureCode)
+ ||(EGestureSwipeUp == iPreviousGestureCode)
+ ||(EGestureSwipeDown == iPreviousGestureCode))
+ {
+ SetupAnimatedPan();
+ }
+ }
+
+void CGlxZoomPanEventHandler::SetupAnimatedPan()
+ {
+ TRACER("CGlxZoomPanEventHandler::SetupAnimatedPan");
+
+ CancelAnimationTimer();
+
+ iZoomAnimationTimer->Start( KGlxPanInertiaFrameInmS,
+ KGlxPanInertiaFrameInmS,
+ TCallBack( PanInertiaFrameElapsed,(TAny*)this) );
+
+ }
+
+
+TInt CGlxZoomPanEventHandler::PanInertiaFrameElapsed(TAny* aPtr)
+ {
+ TRACER("CGlxZoomPanEventHandler::PanInertiaFrameElapsed");
+
+ CGlxZoomPanEventHandler* self = static_cast<CGlxZoomPanEventHandler*>(aPtr);
+
+ self->NextStepInerticPan();
+ return 0;
+
+ }
+
+
+void CGlxZoomPanEventHandler::NextStepInerticPan()
+ {
+ TRACER("CGlxZoomPanEventHandler::NextStepInerticPan");
+
+ TPoint inertiaOffset = iMathsEngine.LastPanOffset();
+
+ if ( (10 >= Abs(inertiaOffset.iX )) && (10 >= Abs(inertiaOffset.iY) ))
+ {
+ CancelAnimationTimer();
+ }
+ else
+ {
+ TPoint topLeftCorner(0,0);
+ TBool thresholdReached = EFalse;
+ iMathsEngine.Pan(inertiaOffset, topLeftCorner, EGlxPanIncrementInertic, &thresholdReached);
+
+ iZoomEventHandler.HandleViewPortParametersChanged(topLeftCorner, KGlxAnimationTimeDrag);
+
+ // we dont want to continue animated PAN if we have reached one end of the image.
+ if (thresholdReached)
+ {
+ CancelAnimationTimer();
+ }
+ }
+ }
+
+void CGlxZoomPanEventHandler::SetPreviousEventCode(const TGestureCode aCode )
+ {
+ TRACER("CGlxZoomPanEventHandler::SetPreviousEventCode(const TGestureCode aCode )");
+
+ iPreviousGestureCode = aCode;
+ }
+
+// -----------------------------------------------------------------------------
+// HandlePinchEvent
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HandlePinchEventL(const GestureHelper::MGestureEvent& aEvent )
+ {
+ TRACER("CGlxZoomControl::HandlePinchEvent(GestureHelper::MGestureEvent&)");
+
+ // Ignore events when we are animating in Zoom
+ if (iIsZoomingInAnimatedState)
+ {
+ return;
+ }
+
+ TPoint pinchFocus = aEvent.PinchCentrePoint();
+ TInt pinchPercentage = aEvent.PinchPercent(); // Wrong convention in variable nomenclature but better than ratioInPercentOfChangeInPinchDistance which is incidentally correct
+
+ // pinchPercentage == 100 => No change in finger distance => No Zoom.
+ // A negative Pinch percentage signifies an error in calculations. So NOT handling these
+ if ( (pinchPercentage != 100)
+ && (pinchPercentage > 0) )
+ {
+ Zoom(0, pinchPercentage, EZoomIn, &pinchFocus);
+ }
+
+ HideScreenFurniture();
+ }
+
+// -----------------------------------------------------------------------------
+// HandleDoubleTap
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HandleDoubleTap(const GestureHelper::MGestureEvent& aEvent )
+ {
+ TRACER("CGlxZoomControl::HandleDoubleTap(GestureHelper::MGestureEvent&)");
+
+ // Ignore events when we are animating in Zoom
+ if (iIsZoomingInAnimatedState)
+ {
+ return;
+ }
+
+ SetupAnimatedZoom(EZoomOut);
+ }
+
+// -----------------------------------------------------------------------------
+// HandleSingleTap
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HandleSingleTap(const GestureHelper::MGestureEvent& aEvent )
+ {
+ TRACER("CGlxZoomControl::HandleSingleTap(GestureHelper::MGestureEvent&)");
+
+ // Ignore events when we are animating in Zoom
+ if (iIsZoomingInAnimatedState)
+ {
+ return;
+ }
+
+ ShowScreenFurniture(KGlxScreenTimeout);
+ }
+
+// ---------------------------------------------------------------------------
+// UiTimeOut: Hides the screen furniture once the Timeout happens
+// ---------------------------------------------------------------------------
+//
+TInt CGlxZoomPanEventHandler::UiTimeOut(TAny* aSelf)
+ {
+ TRACER("CGlxZoomControl::UiTimeOut");
+ if(aSelf)
+ {
+ CGlxZoomPanEventHandler* self = static_cast <CGlxZoomPanEventHandler*> (aSelf);
+ //retreive the UI state.
+ if(EUiOn == self->iZoomUiState)
+ {
+ self->HideScreenFurniture();
+ }
+ }
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// ZoomOutTimerL
+// ---------------------------------------------------------------------------
+//
+TInt CGlxZoomPanEventHandler::ZoomOutTimerL(TAny* aSelf)
+ {
+ TRACER("CGlxZoomControl::ZoomOutTimerL");
+ if(aSelf)
+ {
+ CGlxZoomPanEventHandler* self = static_cast <CGlxZoomPanEventHandler*> (aSelf);
+ self->CallZoomOutL();
+ }
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CallZoomOutL
+// ---------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::CallZoomOutL()
+ {
+ TRACER("CGlxZoomPanEventHandler::CallZoomOutL()");
+ iZoomEventHandler.HandleZoomOutL(KGlxZoomOutCommand);
+ }
+
+//----------------------------------------------------------------------------------
+// ZoomTimerCallback:Callback function for the Zoom timer
+//----------------------------------------------------------------------------------
+//
+TInt CGlxZoomPanEventHandler::ZoomIntervalExpired(TAny* aPtr)
+ {
+ TRACER("CGlxZoomControl::ZoomIntervalExpired ");
+ CGlxZoomPanEventHandler* self = static_cast<CGlxZoomPanEventHandler*>(aPtr);
+ self->DoZoom();
+ return 0; // Timer has finished
+ }
+
+//----------------------------------------------------------------------------------
+// PanIntervalExpired:Callback function for the pan timer
+//----------------------------------------------------------------------------------
+//
+TInt CGlxZoomPanEventHandler::PanIntervalExpired(TAny* aPtr)
+ {
+ TRACER("CGlxZoomPanEventHandler::PanIntervalExpired ");
+ GLX_LOG_INFO("PanIntervalExpired ");
+ CGlxZoomPanEventHandler* self = static_cast<CGlxZoomPanEventHandler*>(aPtr);
+ self->DoPan();
+ return 0; // Timer has finished
+ }
+
+//----------------------------------------------------------------------------------
+// DoZoom:calls zooming function and updates the slider value
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::DoZoom()
+ {
+ TRACER("CGlxZoomPanEventHandler::DoZoom ");
+ Zoom(0, 0, iZoomMode);
+ }
+
+
+//----------------------------------------------------------------------------------
+// DoPan:calls Panning function.
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::DoPan()
+ {
+ TRACER("CGlxZoomPanEventHandler::DoPan ");
+
+ TBool atPanThreshold = EFalse;
+ TPoint topLeftCorner;
+ iMathsEngine.Pan(iPanDirection, topLeftCorner, EGlxPanIncrementExponential, &atPanThreshold);
+
+ iZoomEventHandler.HandleViewPortParametersChanged(topLeftCorner, KGlxAnimationTimekeyPan);
+
+ if ( atPanThreshold )
+ {
+ CancelZoomPanTimer();
+ }
+
+ iMathsEngine.UpdatePanFactor(iPanTime);
+ }
+
+
+//----------------------------------------------------------------------------------
+// OrientationChanged
+//----------------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::OrientationChanged(const TRect& aNewScreenRect)
+ {
+ TRACER("CGlxZoomPanEventHandler::OrientationChanged ");
+
+ Zoom(0, 0, iZoomMode) ;
+
+ iMathsEngine.OrientationChanged(aNewScreenRect);
+ }
+
+// -----------------------------------------------------------------------------
+// ShowSlider
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::ShowScreenFurniture(TTimeIntervalMicroSeconds32 aTimeout)
+ {
+ TRACER("CGlxZoomPanEventHandler::ShowScreenFurniture()");
+
+ iZoomEventHandler.HandleShowUi(ETrue);
+
+ if (aTimeout.Int())
+ {
+ StartUITimer(aTimeout,aTimeout,TCallBack( UiTimeOut,this ));
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// HideScreenFurniture
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HideScreenFurniture()
+ {
+ TRACER("CGlxZoomPanEventHandler::HideScreenFurniture()");
+
+ iZoomEventHandler.HandleShowUi(EFalse);
+ CancelUITimer();
+ }
+
+
+// -----------------------------------------------------------------------------
+// ActivateZoom
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::ActivateZoom(TInt /*aInitialZoomRatio*/,
+ TSize aImageSize,
+ TZoomStartMode aStartMode,
+ TInt aMinSliderRange,
+ TInt aMaxSliderRange,
+ TSize& aOriginalDimensions,
+ TPoint* aZoomFocus)
+ {
+ TRACER("CGlxZoomPanEventHandler::ActivateZoom");
+
+ TPoint center(aImageSize.iWidth/2 ,aImageSize.iHeight/2 );
+ TSize imageSize(aImageSize.iWidth, aImageSize.iHeight);
+
+ TSize screenSize = TSize(AlfUtil::ScreenSize());
+
+ GLX_LOG_INFO2("ActivateZoom : Center = [%d,%d], ",
+ TInt(center.iX),
+ TInt(center.iY)
+ );
+
+ // A zoom ratio is calculated by multiplying the the new virtual size with 100 and dividing it with the original size.
+ // this division using integers might cause truncation. The +1 is added to make sure that every such truncation
+ // is pegged to the next higher integer than the next lower, thus ensuring that the zoom ratio in the zoom mode will always
+ // be greater than that in the full screen mode.
+ //
+ // The only other solution is to introduce a real number for this calculation. But do we really need such a deep level of accuracy?
+ iMinZoomRatio = iZoomRatio = aMinSliderRange + 1;
+ iMaxZoomRatio = aMaxSliderRange ;
+
+ iMathsEngine.Initialize(center,
+ screenSize,
+ imageSize,
+ aOriginalDimensions,
+ iZoomRatio
+ );
+
+ //initially show the slider,so set the state to slider visible
+ TPoint viewPortTopLeft(0,0);
+ TSize viewPortDimension(0,0);
+ iZoomMode = EZoomIn;
+
+ switch(aStartMode)
+ {
+ case EZoomStartKey :
+ {
+ StartZoomTimer();
+ }
+ break;
+ case EZoomStartDoubleTap :
+ {
+ if (!iIsZoomingInAnimatedState)
+ {
+ if (aZoomFocus)
+ {
+ iZoomFocus.iX = aZoomFocus->iX ;
+ iZoomFocus.iY = aZoomFocus->iY ;
+ }
+ SetupAnimatedZoom(EZoomIn, &iZoomFocus);
+ }
+ }
+ break;
+ case EZoomStartPinch:
+ {
+ iZoomRatio = iMathsEngine.Zoom(EZoomIn, aMinSliderRange,
+ viewPortTopLeft, viewPortDimension);
+
+ iZoomEventHandler.HandleViewPortParametersChanged(viewPortTopLeft , 0,
+ &viewPortDimension, iZoomRatio);
+ iZoomEventHandler.HandleShowUi(EFalse);
+ }
+ break;
+ case EZoomStartSlider :
+ break;
+ default:
+ break;
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// DeactivateZoom
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::DeactivateZoom()
+ {
+ TRACER("CGlxZoomPanEventHandler::DeactivateZoom()");
+
+ iZoomMode = EZoomOut;
+ iIsZoomingInAnimatedState = EFalse ;
+ CancelZoomPanTimer();
+ CancelUITimer();
+ CancelAnimationTimer();
+ }
+
+// -----------------------------------------------------------------------------
+// HandleEvent
+// -----------------------------------------------------------------------------
+//
+// Todo: Combine both these HandleEvents
+TBool CGlxZoomPanEventHandler::HandleEvent( const TAlfEvent& aEvent )
+ {
+ TRACER("CGlxZoomControl::HandleEvent()");
+
+ TBool eventHandledState = EFalse;
+
+ if (iZoomActivated)
+ {
+ if(!aEvent.IsCustomEvent())
+ {
+ eventHandledState = EFalse;
+ }
+ else
+ {
+ GLX_LOG_INFO("CGlxZoomPanEventHandler::HandleEvent: Custom Event.");
+ TInt EventID = aEvent.CustomParameter();
+
+ switch(EventID)
+ {
+ case ETypePrimaryValueChange:
+ {
+ GLX_LOG_INFO(" CGlxZoomPanEventHandler::HandleEvent: ETypePrimaryValueChange." );
+
+ MulSliderPos* dataPtr = (MulSliderPos*)(aEvent.CustomEventData());
+ TInt currentSliderValue = dataPtr->mCurrentValue;
+
+ // is current value within accetable ranges.
+ if ( currentSliderValue > iMinZoomRatio
+ && currentSliderValue <= iMaxZoomRatio )
+ {
+ Zoom(currentSliderValue, 0, EZoomIn);
+ }
+ else if (currentSliderValue <= iMinZoomRatio)
+ {
+ CallZoomOutL();
+ }
+ eventHandledState = ETrue;
+ }
+ break;
+
+ case ECustomEventIconClick :
+ {
+ //The Slider is held by user,so cancel the UI Timer
+ //When the slider is held ,the screen furniture shouldn't disappear
+ GLX_LOG_INFO( " CGlxZoomControl::offerEvent,ECustomEventIconClick");
+ CancelUITimer();
+ eventHandledState = ETrue;
+ }
+ break;
+
+ case ECustomEventIconRelease:
+ {
+ //The slider is not held, by the user,start the ui timer to hide the screen furniture
+ GLX_LOG_INFO( " CGlxZoomControl::offerEvent,ECustomEventIconRelease");
+ StartUITimer(KGlxScreenTimeout, KGlxScreenTimeout, TCallBack( UiTimeOut,this ) );
+ eventHandledState = ETrue;
+ }
+ break;
+
+ default:
+ {
+ GLX_LOG_INFO(" CGlxZoomPanEventHandler::HandleEvent default");
+ eventHandledState = EFalse;
+ break;
+ }
+ }
+ }
+ }
+ return eventHandledState ;
+ }
+
+// -----------------------------------------------------------------------------
+// HandleEvent
+// -----------------------------------------------------------------------------
+//
+TBool CGlxZoomPanEventHandler::HandleEventL(const TAlfEvent &aEvent)
+ {
+ TRACER("CGlxZoomControl::HandleEventL()");
+
+ TBool consumed = EFalse;
+
+ if (iZoomActivated)
+ {
+ if (aEvent.IsKeyEvent() )
+ {
+ GLX_LOG_INFO(" CGlxZoomPanEventHandler::HandleEvent KeyEvent");
+ consumed = HandlekeyEvents(aEvent);
+ }
+ else if(aEvent.IsPointerEvent() )
+ {
+ GLX_LOG_INFO(" CGlxZoomPanEventHandler::HandleEvent PointerEvent ");
+ consumed = iZoomEventHandler.HandlePointerEventsL(aEvent);
+ }
+ }
+ return consumed;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Zoom
+// -----------------------------------------------------------------------------
+//
+
+
+void CGlxZoomPanEventHandler::Zoom(TInt aExpectedZoomLevel, TInt aRelativeZoomFactor, TZoomMode aZoomMode, TPoint* aZoomFocus)
+ {
+ TRACER("CGlxZoomControl::ZoomL( )");
+
+ TPoint viewPortTopLeft(0,0);
+ TSize viewPortDimension(0,0);
+ TBool atZoomThreshold = EFalse;
+
+ iZoomRatio = iMathsEngine.Zoom(aZoomMode,
+ aExpectedZoomLevel,
+ viewPortTopLeft,
+ viewPortDimension,
+ &atZoomThreshold,
+ aZoomFocus,
+ aRelativeZoomFactor);
+
+ iZoomEventHandler.HandleViewPortParametersChanged(viewPortTopLeft, 0,
+ &viewPortDimension, iZoomRatio);
+
+ if( atZoomThreshold )
+ {
+ CancelZoomPanTimer();
+ if (iZoomRatio <= iMinZoomRatio)
+ {
+ CallZoomOutL();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ZoomIsActivated
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::SetZoomActivated(TBool aIsActivated)
+ {
+ TRACER("CGlxZoomPanEventHandler::ZoomIsActivated");
+ iZoomActivated = aIsActivated;
+ }
+
+// -----------------------------------------------------------------------------
+// SetZoomUiState
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::SetZoomUiState(TUiState aZoomUiState)
+ {
+ TRACER("CGlxZoomPanEventHandler::ZoomIsActivated");
+ iZoomUiState = aZoomUiState;
+ GLX_LOG_INFO1("CGlxZoomPanEventHandler::SetZoomUiState :=%d",iZoomUiState);
+ }
+
+// -----------------------------------------------------------------------------
+// ZoomUiState
+// -----------------------------------------------------------------------------
+//
+TUiState CGlxZoomPanEventHandler::ZoomUiState()
+ {
+ TRACER("CGlxZoomPanEventHandler::ZoomUiState");
+ return iZoomUiState ;
+ }
+
+// -----------------------------------------------------------------------------
+// HandleMultiTouchReleased
+// -----------------------------------------------------------------------------
+//
+void CGlxZoomPanEventHandler::HandleMultiTouchReleased()
+ {
+ TRACER("CGlxZoomPanEventHandler::HandleMultiTouchReleased");
+
+// ShowScreenFurniture(KGlxScreenTimeout);
+ }