diff -r 000000000000 -r 4e91876724a2 photosgallery/viewframework/views/zoomview/src/glxzoomeventhandler.cpp --- /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 + +// Antariksh +#include // AlfUtil +#include // For Slider events + +//Photos Headers +#include // For Tracer +#include // For Log + +#include // For MGlxUiCommandHandler +#include +#include +#include +#include + + +// 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(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(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 (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 (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(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(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); + }