imageeditor/plugins/RedEyePlugin/src/ImageEditorRedEyeReductionControl.cpp
changeset 1 edfc90759b9f
equal deleted inserted replaced
0:57d4cdd99204 1:edfc90759b9f
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description: 
       
    16 * Control class for RedEyeReduction plugin.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 //  INCLUDES
       
    22 #include <fbs.h>
       
    23 #include <badesca.h>
       
    24 #include <gdi.h>
       
    25 #include <eikenv.h>
       
    26 #include <bitdev.h>
       
    27 #include <eikmenup.h>
       
    28 #include <coehelp.h>
       
    29 
       
    30 #include <aknview.h>
       
    31 #include <aknutils.h>
       
    32 
       
    33 #include <ImageEditorUI.mbg>
       
    34 
       
    35 
       
    36 #include <AknInfoPopupNoteController.h> 
       
    37 #include <redeyereduction.rsg> 
       
    38 #include <bautils.h> 
       
    39 #include <ConeResLoader.h> 
       
    40 #include <csxhelp/sie.hlp.hrh>
       
    41 
       
    42 #ifdef RD_TACTILE_FEEDBACK 
       
    43 #include <touchfeedback.h>
       
    44 #endif /* RD_TACTILE_FEEDBACK  */
       
    45 
       
    46 #include "ImageEditorUI.hrh"
       
    47 #include "ImageEditorPluginBase.hrh"
       
    48 #include "RedEyeReduction.hrh"
       
    49 #include "DrawUtils.h"
       
    50 #include "PluginInfo.h"
       
    51 #include "SystemParameters.h"
       
    52 #include "ImageEditorUids.hrh"
       
    53 
       
    54 #include "ImageEditorRedEyeReductionControl.h"
       
    55 #include "ImageEditorUIDefs.h" 
       
    56 #include "iepb.h"
       
    57 #include "definitions.def"
       
    58 
       
    59 // 	DEBUG LOG
       
    60 #include "imageeditordebugutils.h"
       
    61 _LIT(KRedEyeReductionPluginLogFile, "RedEyeReductionPlugin.log");
       
    62 
       
    63 //  CONSTANTS
       
    64 const TReal KPosParamMin        = 0.0;
       
    65 const TReal KPosParamMax        = 1.0;
       
    66 const TReal KPosParamStep       = 0.01;
       
    67 const TReal KPosParamDef        = 0.5;
       
    68 
       
    69 const TReal KRadiusParamMin      = 0.0;
       
    70 const TReal KRadiusParamMax      = 0.4;
       
    71 const TReal KRadiusParamStep     = 0.0025;
       
    72 const TReal KRadiusParamDef      = 0.05;
       
    73 
       
    74 const TInt KMoveSelectionIndex    = 0;
       
    75 const TInt KResizeSelectionIndex  = 1;
       
    76 
       
    77 // Default values from CPreviewControlBase not used
       
    78 const TInt KRedEyeFastKeyTimerDelayInMicroseconds = 500000;
       
    79 const TInt KRedEyeFastKeyTimerIntervalInMicroseconds = 50000;
       
    80 const TInt KRedEyeFastKeyTimerMultiplyThresholdInTicks = 9;
       
    81 const TInt KRedEyeBigNavigationStepMultiplier = 3;
       
    82 
       
    83 // Touch constants
       
    84 const TInt KTouchScaleMaxStepCount  = 50;
       
    85 
       
    86 // Panic category
       
    87 _LIT (KComponentName, "ImageEditorRedEyeReduction" );
       
    88 
       
    89 // Resource file name
       
    90 _LIT (KPgnResourceFile, "redeyereduction.rsc"); 
       
    91 
       
    92 //=============================================================================
       
    93 TInt CImageEditorRedEyeReductionControl::DancingAntzCallback (TAny * aPtr)
       
    94 {
       
    95 	((CImageEditorRedEyeReductionControl *)aPtr)->OnDancingAntzCallBack();
       
    96 	return KErrNone;
       
    97 }
       
    98 
       
    99 //=============================================================================
       
   100 TInt CImageEditorRedEyeReductionControl::FastKeyCallback (TAny * aPtr)
       
   101 {
       
   102 	TRAPD( err, ((CImageEditorRedEyeReductionControl *)aPtr)->OnFastKeyCallBackL() );
       
   103 	return err;
       
   104 }
       
   105 
       
   106 //=============================================================================
       
   107 CImageEditorRedEyeReductionControl * CImageEditorRedEyeReductionControl::NewL (
       
   108 	const TRect &		aRect,
       
   109 	CCoeControl	*		aParent
       
   110 	)
       
   111 {
       
   112     CImageEditorRedEyeReductionControl * self = new (ELeave) CImageEditorRedEyeReductionControl;
       
   113     CleanupStack::PushL (self);
       
   114     self->ConstructL (aRect, aParent);
       
   115     CleanupStack::Pop ();   // self
       
   116     return self;
       
   117 }
       
   118 
       
   119 //=============================================================================
       
   120 CImageEditorRedEyeReductionControl::CImageEditorRedEyeReductionControl () :
       
   121 iState( ERedEyeReductionStateMin ),
       
   122 iX( KPosParamDef ),
       
   123 iY( KPosParamDef ),
       
   124 iR( KRadiusParamDef ),
       
   125 iHandleEventKeys (ETrue),
       
   126 iTickCount (0),
       
   127 iNaviStepMultiplier (KDefaultSmallNavigationStepMultiplier),
       
   128 iReadyToRender(ETrue),
       
   129 iDoNotUpdateParameters(EFalse),
       
   130 iCursorDragEnabled( EFalse )
       
   131 {
       
   132     
       
   133 }
       
   134 
       
   135 //=============================================================================
       
   136 CImageEditorRedEyeReductionControl::~CImageEditorRedEyeReductionControl ()
       
   137 {
       
   138     delete iCrossHair;
       
   139     delete iCrossHairMask;
       
   140     iUndoArray.Close();
       
   141     if( iTimer )
       
   142     {
       
   143         iTimer->Cancel();
       
   144     }
       
   145     delete iTimer;
       
   146     iVisibleImageRectPrev = NULL;
       
   147     iVisibleImageRect = NULL;
       
   148     iEditorView = NULL;
       
   149     iItem = NULL;
       
   150     
       
   151     delete iPopupController;
       
   152 	delete iTooltipLocate;
       
   153 	delete iTooltipOutline;
       
   154 
       
   155 }
       
   156 
       
   157 //=============================================================================
       
   158 void CImageEditorRedEyeReductionControl::ConstructL (
       
   159 	const TRect &		/*aRect*/,
       
   160 	CCoeControl	*		aParent
       
   161 	)
       
   162 {
       
   163 	LOG_INIT(KRedEyeReductionPluginLogFile);
       
   164 	LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::ConstructL" );
       
   165 
       
   166 	//	Set parent window
       
   167 	SetContainerWindowL (*aParent);
       
   168 
       
   169     //	Create timer for fast keys and dancing ants
       
   170     iTimer = CPeriodic::NewL (CActive::EPriorityStandard);
       
   171 
       
   172 	//	Create CROSSHAIR image
       
   173     SDrawUtils::GetIndicatorBitmapL( 
       
   174         iCrossHair, 
       
   175         iCrossHairMask, 
       
   176         EMbmImageeditoruiQgn_indi_imed_cursor_super, // cross-hair
       
   177         EMbmImageeditoruiQgn_indi_imed_cursor_super_mask
       
   178         );
       
   179 
       
   180 	iPopupController = CAknInfoPopupNoteController::NewL();    
       
   181 	
       
   182 	TFileName resourcefile;
       
   183 	resourcefile.Append(KPgnResourcePath);
       
   184 	resourcefile.Append(KPgnResourceFile);
       
   185     User::LeaveIfError( CompleteWithAppPath( resourcefile ) );
       
   186 
       
   187     //	Read tooltip resources  
       
   188     //  (RConeResourceLoader selects the language using BaflUtils::NearestLanguageFile)
       
   189     RConeResourceLoader resLoader ( *CEikonEnv::Static() );
       
   190     CleanupClosePushL ( resLoader );
       
   191 	resLoader.OpenL ( resourcefile );
       
   192 	
       
   193 	iTooltipLocate = CEikonEnv::Static()->AllocReadResourceL(R_TOOLTIP_REDEYE_LOCATE);    
       
   194 	iTooltipOutline = CEikonEnv::Static()->AllocReadResourceL(R_TOOLTIP_REDEYE_OUTLINE);    
       
   195       
       
   196     CleanupStack::PopAndDestroy(); // resLoader
       
   197 
       
   198 #ifdef RD_TACTILE_FEEDBACK 
       
   199     iTouchFeedBack = MTouchFeedback::Instance();
       
   200 #endif /* RD_TACTILE_FEEDBACK  */
       
   201     
       
   202 	//	Activate control
       
   203     ActivateL();
       
   204     
       
   205     EnableDragEvents();
       
   206 }
       
   207 
       
   208 //=============================================================================
       
   209 void CImageEditorRedEyeReductionControl::SetView (CAknView * aView)
       
   210 {
       
   211     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::SetView" );
       
   212     
       
   213     iEditorView = aView;
       
   214 }
       
   215 
       
   216 //=============================================================================
       
   217 void CImageEditorRedEyeReductionControl::SetSelectedUiItemL (CPluginInfo * aItem)
       
   218 {
       
   219     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::SetSelectedUiItemL" );
       
   220 
       
   221     iItem = aItem;
       
   222 }
       
   223 
       
   224 //=============================================================================
       
   225 void CImageEditorRedEyeReductionControl::PrepareL ()
       
   226 {
       
   227     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::PrepareL" );
       
   228 
       
   229 #ifdef __TOUCH_ONLY_DEVICE_RER_PLUGIN_ACTION__         
       
   230     // The whole crosshair set state is skipped totally in touch-only devices
       
   231     ToResizeStateL();
       
   232 #else        
       
   233     ToMoveStateL();
       
   234 #endif    
       
   235                 
       
   236     // Store parameters for the initial filter. 
       
   237     // This is a special case. For the other filters, the parameters
       
   238     // are stored implicitly when calling 
       
   239     iEditorView->HandleCommandL (EImageEditorStoreParameters);
       
   240 }
       
   241 
       
   242 //=============================================================================
       
   243 TKeyResponse CImageEditorRedEyeReductionControl::OfferKeyEventL (
       
   244     const TKeyEvent &   aKeyEvent,
       
   245     TEventCode          aType
       
   246     )
       
   247 {
       
   248     TKeyResponse response = EKeyWasNotConsumed;
       
   249 
       
   250     //  If busy, do not handle anything
       
   251     if ( Busy() )
       
   252     {
       
   253         response = EKeyWasConsumed;
       
   254     }
       
   255 
       
   256     //  EEventKey
       
   257     else if (EEventKey == aType && iHandleEventKeys)
       
   258     {
       
   259         
       
   260 		switch (aKeyEvent.iCode)
       
   261 		{
       
   262 
       
   263 			case EKeyDownArrow:
       
   264 			{
       
   265                 //  Adjust crop point
       
   266                 NaviDown();
       
   267                 DrawNow();
       
   268                 response = EKeyWasConsumed;
       
   269                 break;
       
   270 			}
       
   271 
       
   272 			case EKeyUpArrow:
       
   273 			{
       
   274                 //  Adjust crop point
       
   275                 NaviUp();
       
   276                 DrawNow();
       
   277                 response = EKeyWasConsumed;
       
   278                 break;
       
   279 			}
       
   280 
       
   281 			case EKeyRightArrow:
       
   282 			{
       
   283                 //  Adjust crop point
       
   284                 NaviRight();
       
   285                 DrawNow();
       
   286 				response = EKeyWasConsumed;
       
   287                 break;
       
   288 			}
       
   289 
       
   290             case EKeyLeftArrow:
       
   291 			{
       
   292                 //  Adjust crop point
       
   293                 NaviLeft();
       
   294                 DrawNow();
       
   295 				response = EKeyWasConsumed;
       
   296                 break;
       
   297 			}
       
   298 
       
   299             case EKeyOK:
       
   300             case EKeyEnter:
       
   301             {
       
   302                 KeyOkL();
       
   303                 DrawNow();
       
   304                 response = EKeyWasConsumed;
       
   305                 break;
       
   306             }
       
   307 
       
   308 			default:
       
   309 			{
       
   310 				break;
       
   311 			}
       
   312 		}
       
   313     }
       
   314 
       
   315     else if (EEventKey == aType && !iHandleEventKeys)
       
   316     {
       
   317         response = EKeyWasConsumed;
       
   318     }
       
   319 
       
   320     //  EEventKeyDown
       
   321     else if (EEventKeyDown == aType)
       
   322     {
       
   323         switch (aKeyEvent.iScanCode)
       
   324         {
       
   325             case EStdKeyLeftArrow:
       
   326             case EStdKeyRightArrow:
       
   327             case EStdKeyUpArrow:
       
   328             case EStdKeyDownArrow:
       
   329             {   
       
   330                 iPressedKeyScanCode = aKeyEvent.iScanCode;
       
   331                 StartFastKeyTimer();
       
   332                 response = EKeyWasConsumed;
       
   333                 break;
       
   334             }
       
   335             default:
       
   336                 break;
       
   337         }
       
   338     }
       
   339 
       
   340     //  EEventKeyUp
       
   341     else if (EEventKeyUp == aType)
       
   342     {
       
   343         if (aKeyEvent.iScanCode == iPressedKeyScanCode)
       
   344         {
       
   345             iHandleEventKeys = ETrue;
       
   346             if (iState == ERedEyeReductionStateResizeSelection)
       
   347             {
       
   348                 StartDancingAntzTimer();
       
   349             }
       
   350             else if( iTimer )
       
   351             {
       
   352                 iTimer->Cancel();
       
   353             }
       
   354             response = EKeyWasConsumed;
       
   355             
       
   356             ShowTooltip();
       
   357         }
       
   358     }
       
   359 
       
   360     return response;
       
   361 }
       
   362     
       
   363 //=============================================================================
       
   364 void CImageEditorRedEyeReductionControl::SizeChanged()
       
   365 {
       
   366 }
       
   367 
       
   368 //=============================================================================
       
   369 TRect CImageEditorRedEyeReductionControl::GetParam ()
       
   370 {
       
   371 	LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::GetParam" );
       
   372 	if (iUndoArray.Count() == 0 || iDoNotUpdateParameters)
       
   373 	{
       
   374 		LOG( KRedEyeReductionPluginLogFile, "\tiRedEyeRect: (0,0), (0,0)" );
       
   375 		return TRect();
       
   376 	}
       
   377 	else
       
   378 	{
       
   379 		LOGFMT4( KRedEyeReductionPluginLogFile, "\tiRedEyeRect: (%d,%d), (%d,%d)", iRedEyeRect.iTl.iX, iRedEyeRect.iTl.iY, iRedEyeRect.iBr.iX, iRedEyeRect.iBr.iY );
       
   380 		ComputeParams();
       
   381 		return iRedEyeRect;
       
   382 	}
       
   383 }
       
   384 
       
   385 //=============================================================================
       
   386 void CImageEditorRedEyeReductionControl::SetSystemParameters (const CSystemParameters * aPars) 
       
   387 {
       
   388     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::SetSystemParameters" );
       
   389 
       
   390     iVisibleImageRect = &(aPars->VisibleImageRect()); 
       
   391     iVisibleImageRectPrev = &(aPars->VisibleImageRectPrev());
       
   392 	iSysPars = aPars;
       
   393 
       
   394     __ASSERT_ALWAYS( iVisibleImageRectPrev && iVisibleImageRectPrev, User::Panic(KComponentName, KErrNotReady) );
       
   395     LOGFMT4( KRedEyeReductionPluginLogFile, "\tiVisibleImageRect: (%d,%d), (%d,%d)", iVisibleImageRect->iTl.iX, iVisibleImageRect->iTl.iY, iVisibleImageRect->iBr.iX, iVisibleImageRect->iBr.iY );
       
   396     LOGFMT2( KRedEyeReductionPluginLogFile, "\tVisible image rect size: %d,%d", (iVisibleImageRect->iBr.iX - iVisibleImageRect->iTl.iX) + 1, (iVisibleImageRect->iBr.iY - iVisibleImageRect->iTl.iY) + 1 );
       
   397     LOGFMT2( KRedEyeReductionPluginLogFile, "\tSize(): %d,%d", Size().iWidth, Size().iHeight );
       
   398     LOGFMT4( KRedEyeReductionPluginLogFile, "\tiVisibleImageRectPrev: (%d,%d), (%d,%d)", iVisibleImageRectPrev->iTl.iX, iVisibleImageRectPrev->iTl.iY, iVisibleImageRectPrev->iBr.iX, iVisibleImageRectPrev->iBr.iY );
       
   399     LOGFMT2( KRedEyeReductionPluginLogFile, "\tiVisibleImageRectPrev size: %d,%d", iVisibleImageRectPrev->Width(), iVisibleImageRectPrev->Height() );
       
   400 }
       
   401 
       
   402 //=============================================================================
       
   403 void CImageEditorRedEyeReductionControl::HandlePluginCommandL (const TInt aCommand)
       
   404 {
       
   405     LOGFMT( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::HandlePluginCommandL: %d", aCommand );
       
   406 
       
   407     switch (aCommand) 
       
   408     {
       
   409         case EImageEditorFocusGained:
       
   410         {
       
   411             if (iState == ERedEyeReductionStateResizeSelection)
       
   412             {
       
   413                 StartDancingAntzTimer();
       
   414             }
       
   415             break;
       
   416         }
       
   417         case EImageEditorFocusLost:
       
   418         {
       
   419             if (iTimer)
       
   420             {
       
   421                 iTimer->Cancel();
       
   422             }
       
   423             break;
       
   424         }
       
   425         case EPgnSoftkeyIdCancel:
       
   426         {
       
   427             CancelPluginL();
       
   428             break;
       
   429         }
       
   430         case EPgnSoftkeyIdDone:
       
   431         {        
       
   432             iDoNotUpdateParameters = ETrue;
       
   433             iEditorView->HandleCommandL (EImageEditorApplyPlugin);
       
   434             break;
       
   435         }
       
   436         case ERedEyeReductionPgnMenuCmdSet:
       
   437         case EPgnSoftkeyIdSet:
       
   438         {
       
   439             KeyOkL();
       
   440             DrawNow();
       
   441             break;
       
   442         }
       
   443         case ERedEyeReductionPgnMenuCmdReduceRed:
       
   444         case EPgnSoftkeyIdReduceRed:
       
   445         {
       
   446             KeyOkL();
       
   447             DrawNow();
       
   448             break;
       
   449         }
       
   450         case ERedEyeReductionPgnMenuCmdUndo:
       
   451         {
       
   452             UndoL();
       
   453             iEditorView->HandleCommandL (EImageEditorUpdateSoftkeys);
       
   454             break;
       
   455         }
       
   456         case ERedEyeReductionPgnMenuCmdCancel:
       
   457         {
       
   458             CancelPluginL();
       
   459             break;
       
   460         }
       
   461         case EImageEditorPreGlobalZoomChange:
       
   462         case EImageEditorPreGlobalPanChange:
       
   463 		{
       
   464 			iDoNotUpdateParameters = ETrue;
       
   465 			break;
       
   466 		}
       
   467         case EImageEditorGlobalZoomChanged:
       
   468         case EImageEditorGlobalPanChanged:
       
   469         {
       
   470 			iDoNotUpdateParameters = EFalse;
       
   471 			DrawNow();
       
   472 	        break;
       
   473         }
       
   474         
       
   475     	case EImageEditorPreScreenModeChange:
       
   476     	{
       
   477     		TReal relscale = iSysPars->RelScale();
       
   478 			TRect virect = *iVisibleImageRect;
       
   479 			virect.iTl.iX = (TInt)((virect.iTl.iX / relscale) + 0.5);
       
   480 			virect.iTl.iY = (TInt)((virect.iTl.iY / relscale) + 0.5);
       
   481 			virect.iBr.iX = (TInt)((virect.iBr.iX / relscale) + 0.5);
       
   482 			virect.iBr.iY = (TInt)((virect.iBr.iY / relscale) + 0.5);
       
   483 			iLockPoint.iX = virect.iTl.iX + iX * virect.Width();
       
   484 			iLockPoint.iY = virect.iTl.iY + iY * virect.Height();
       
   485     		break;
       
   486     	}
       
   487     	case EImageEditorPostScreenModeChange:
       
   488     	{
       
   489     		TReal relscale = iSysPars->RelScale();
       
   490 			TRect virect = *iVisibleImageRect;
       
   491 			virect.iTl.iX = (TInt)((virect.iTl.iX / relscale) + 0.5);
       
   492 			virect.iTl.iY = (TInt)((virect.iTl.iY / relscale) + 0.5);
       
   493 			virect.iBr.iX = (TInt)((virect.iBr.iX / relscale) + 0.5);
       
   494 			virect.iBr.iY = (TInt)((virect.iBr.iY / relscale) + 0.5);
       
   495 			iX = (TReal)(iLockPoint.iX - virect.iTl.iX) / virect.Width();
       
   496 			iY = (TReal)(iLockPoint.iY - virect.iTl.iY) / virect.Height();
       
   497 			ClipPosition();
       
   498 			DrawNow();
       
   499     		break;
       
   500     	}
       
   501         
       
   502         default:
       
   503         {
       
   504             break;
       
   505         }
       
   506     }
       
   507 }
       
   508 
       
   509 //=============================================================================
       
   510 TInt CImageEditorRedEyeReductionControl::GetSoftkeyIndexL()
       
   511 {
       
   512     
       
   513     TInt index = -1;
       
   514   if ( iState == ERedEyeReductionStateResizeSelection )
       
   515         {
       
   516         if ( !iUndoArray.Count() )
       
   517             {
       
   518             index = 3;
       
   519             }
       
   520         else
       
   521             {
       
   522             index = 1;
       
   523             }            
       
   524         }
       
   525     else if ( iState == ERedEyeReductionStateMoveCrosshair )
       
   526         {
       
   527         if ( !iUndoArray.Count() )
       
   528             {
       
   529             index = 0;
       
   530             }
       
   531         else
       
   532             {
       
   533             index = 2;
       
   534             }  
       
   535         }
       
   536    
       
   537   
       
   538        
       
   539     LOGFMT( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::GetSoftkeyIndexL: %d", index );
       
   540 
       
   541     return index;
       
   542 }
       
   543 
       
   544 //=============================================================================
       
   545 TBitField CImageEditorRedEyeReductionControl::GetDimmedMenuItems()
       
   546 {
       
   547 	LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::GetDimmedMenuItems" );
       
   548 
       
   549     TBitField dimmedMenuItems;
       
   550     TInt count = iItem->MenuItems().Count();
       
   551 
       
   552     switch (iState) 
       
   553     {
       
   554     case ERedEyeReductionStateMoveCrosshair:
       
   555         {
       
   556             // Dim the command ERedEyeReductionPgnMenuCmdReduceRed, and also 
       
   557             // ERedEyeReductionPgnMenuCmdUndo if selecting the first eye.
       
   558             for ( TInt i = 0; i < count; i++)
       
   559             {
       
   560                 // get the menu item id
       
   561                 TInt menuItem = iItem->MenuItems().At(i).iCommandId;
       
   562                 if ( menuItem == ERedEyeReductionPgnMenuCmdReduceRed ||
       
   563                     ( iUndoArray.Count() == 0 && menuItem == ERedEyeReductionPgnMenuCmdUndo) 
       
   564                     )
       
   565                 {
       
   566                     dimmedMenuItems.SetBit( i );
       
   567                 }
       
   568             }
       
   569             break;
       
   570         }
       
   571     case ERedEyeReductionStateResizeSelection:
       
   572         {
       
   573             // Dim the command ERedEyeReductionPgnMenuCmdSet.
       
   574             for ( TInt i = 0; i < count; i++)
       
   575             {
       
   576                 // get the menu item id
       
   577                 TInt menuItem = iItem->MenuItems().At(i).iCommandId;
       
   578                 
       
   579 #ifdef __TOUCH_ONLY_DEVICE_RER_PLUGIN_ACTION__ 
       
   580                 if ( menuItem == ERedEyeReductionPgnMenuCmdSet ||
       
   581                    ( iUndoArray.Count() == 0 && menuItem == ERedEyeReductionPgnMenuCmdUndo))
       
   582                 {
       
   583                     dimmedMenuItems.SetBit( i );
       
   584                 }                
       
   585 #else
       
   586                 if ( menuItem == ERedEyeReductionPgnMenuCmdSet )
       
   587                 {
       
   588                     dimmedMenuItems.SetBit( i );
       
   589                 }
       
   590 #endif                
       
   591                 
       
   592             }
       
   593             break;
       
   594         }
       
   595     default:
       
   596         {
       
   597             ASSERT( EFalse );
       
   598             break;
       
   599         }
       
   600     }
       
   601     return dimmedMenuItems;
       
   602 }
       
   603 
       
   604 //=============================================================================
       
   605 TPtrC CImageEditorRedEyeReductionControl::GetNaviPaneTextL (
       
   606     TBool& aLeftNaviPaneScrollButtonVisibile, 
       
   607     TBool& aRightNaviPaneScrollButtonVisible )
       
   608 {
       
   609     aLeftNaviPaneScrollButtonVisibile = EFalse;
       
   610     aRightNaviPaneScrollButtonVisible = EFalse;
       
   611     return iNaviPaneText;
       
   612 }
       
   613 
       
   614 //=============================================================================
       
   615 void CImageEditorRedEyeReductionControl::Draw (const TRect & aRect) const
       
   616 {
       
   617     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::Draw()" );
       
   618 
       
   619     CPreviewControlBase::DrawPreviewImage (aRect);
       
   620 
       
   621 #ifdef VERBOSE
       
   622     LOGFMT4( KRedEyeReductionPluginLogFile, "\tiVisibleImageRect: (%d,%d), (%d,%d)", iVisibleImageRect->iTl.iX, iVisibleImageRect->iTl.iY, iVisibleImageRect->iBr.iX, iVisibleImageRect->iBr.iY );
       
   623     LOGFMT2( KRedEyeReductionPluginLogFile, "\tVisible image rect size: %d,%d", (iVisibleImageRect->iBr.iX - iVisibleImageRect->iTl.iX) + 1, (iVisibleImageRect->iBr.iY - iVisibleImageRect->iTl.iY) + 1 );
       
   624     LOGFMT2( KRedEyeReductionPluginLogFile, "\tSize(): %d,%d", Size().iWidth, Size().iHeight );
       
   625     LOGFMT4( KRedEyeReductionPluginLogFile, "\tiVisibleImageRectPrev: (%d,%d), (%d,%d)", iVisibleImageRectPrev->iTl.iX, iVisibleImageRectPrev->iTl.iY, iVisibleImageRectPrev->iBr.iX, iVisibleImageRectPrev->iBr.iY );
       
   626     LOGFMT2( KRedEyeReductionPluginLogFile, "\tiVisibleImageRectPrev size: %d,%d", iVisibleImageRectPrev->Width(), iVisibleImageRectPrev->Height() );
       
   627 #endif
       
   628 
       
   629     //  In move state draw the crosshair
       
   630     if ( iState == ERedEyeReductionStateMoveCrosshair )
       
   631     {
       
   632 		//  Get graphics context
       
   633 		CWindowGc & gc = SystemGc();
       
   634 
       
   635 		gc.SetPenStyle (CGraphicsContext::ENullPen);
       
   636 		gc.SetBrushStyle (CGraphicsContext::ENullBrush);
       
   637 
       
   638         TSize chSize = iCrossHair->SizeInPixels();
       
   639 		TPoint center = CursorLocation();
       
   640         gc.BitBltMasked (
       
   641             TPoint(center.iX - (chSize.iWidth >> 1), center.iY - (chSize.iHeight >> 1)), 
       
   642             iCrossHair, 
       
   643             TRect (chSize), 
       
   644             iCrossHairMask, 
       
   645             EFalse
       
   646             );
       
   647     }
       
   648 
       
   649     // In resize state draw the selection circle
       
   650     else if ( iState == ERedEyeReductionStateResizeSelection )
       
   651     {
       
   652 		DrawDancingAntz(Rect());
       
   653     }
       
   654 }
       
   655 
       
   656 //=============================================================================
       
   657 void CImageEditorRedEyeReductionControl::DrawDancingAntz (const TRect & /*aRect*/) const
       
   658 {
       
   659 	//  Get graphics context
       
   660     CWindowGc & gc = SystemGc();
       
   661 
       
   662     //  Compute center point of the area
       
   663     TPoint center = CursorLocation();
       
   664 
       
   665     //  Compute selection rectangle
       
   666     TRect rect ( SelectionRect( center ) ); 
       
   667 
       
   668     //  Draw the "dancing ants" ellipse
       
   669 	gc.SetDrawMode (CGraphicsContext::EDrawModePEN);
       
   670     gc.SetBrushStyle (CGraphicsContext::ENullBrush);
       
   671     gc.SetBrushColor (KRgbBlack);
       
   672 	
       
   673 	//	Draw 
       
   674     gc.SetPenStyle (CGraphicsContext::ESolidPen);
       
   675 	gc.SetPenColor ((iAntFlag) ? (KRgbBlack) : (KRgbWhite));
       
   676     gc.DrawEllipse (rect);
       
   677     
       
   678 	//	Draw dashed line
       
   679 	gc.SetPenStyle (CGraphicsContext::EDashedPen);
       
   680 	gc.SetPenColor ((iAntFlag) ? (KRgbWhite) : (KRgbBlack));
       
   681     gc.DrawEllipse (rect);
       
   682 
       
   683 }
       
   684 
       
   685 //=============================================================================
       
   686 void CImageEditorRedEyeReductionControl::UndoL()
       
   687     {
       
   688     TInt count = iUndoArray.Count();
       
   689 
       
   690     LOGFMT( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::UndoL(): iUndoArray.Count() == %d", count );
       
   691 
       
   692     switch (iState) 
       
   693         {
       
   694         case ERedEyeReductionStateMoveCrosshair:
       
   695             {
       
   696             if ( count > 0 )
       
   697                 {
       
   698     			// Remove the latest selected red eye area
       
   699                 // (It would be possible to set the cursor back to the point 
       
   700                 //  which was the location of the previous eye, but that 
       
   701                 // depends also on the zoom and pan values, which are not 
       
   702                 // available for plugins)
       
   703                 iUndoArray.Remove( count - 1 );
       
   704 
       
   705     			// Undo the filter
       
   706     			iEditorView->HandleCommandL (EImageEditorUndoFilter);
       
   707                 
       
   708     			if ( iUndoArray.Count() == 0)
       
   709 			        {
       
   710                     // One filter is added already when opening the plugin. If 
       
   711                     // this initial filter is undone, we need to create a new one.
       
   712     				iEditorView->HandleCommandL (EImageEditorStoreParameters);
       
   713     				iEditorView->HandleCommandL (EImageEditorAddFilterToEngine);
       
   714 
       
   715 			        }
       
   716                 else
       
   717                     {
       
   718                     // Restore parameters
       
   719                     iRedEyeRect = iUndoArray[ count - 2 ];
       
   720                     }
       
   721                 }
       
   722             break;
       
   723             }
       
   724         case ERedEyeReductionStateResizeSelection:
       
   725             {
       
   726         
       
   727 #ifdef __TOUCH_ONLY_DEVICE_RER_PLUGIN_ACTION__  
       
   728             // in touch-only device do the same thing here in resize state as 
       
   729             // in non-touch device in move state->remove/undo filter 
       
   730             if ( count > 0 )
       
   731                 {
       
   732                     		
       
   733             iUndoArray.Remove( count - 1 );
       
   734 
       
   735     		// Undo the filter
       
   736     		iEditorView->HandleCommandL (EImageEditorUndoFilter);
       
   737             
       
   738     			if ( iUndoArray.Count() == 0)
       
   739     		        {
       
   740                     // One filter is added already when opening the plugin. If this
       
   741                     // initial filter is undone, we need to create a new one.
       
   742     				iEditorView->HandleCommandL (EImageEditorStoreParameters);
       
   743     				iEditorView->HandleCommandL (EImageEditorAddFilterToEngine);
       
   744 
       
   745     		        }
       
   746                 else
       
   747                     {
       
   748                     // Restore parameters
       
   749                     iRedEyeRect = iUndoArray[ count - 2 ];
       
   750                     }
       
   751                 }
       
   752 
       
   753 #else 
       
   754                 
       
   755             // In the resize state consider that undo means
       
   756             // going back to the move crosshair state (non-touch)
       
   757             ToMoveStateL();
       
   758 #endif                                   
       
   759                                    
       
   760             break;
       
   761             }
       
   762         
       
   763         default:
       
   764             {
       
   765             ASSERT( EFalse );
       
   766             break;
       
   767             }
       
   768         }
       
   769 
       
   770     DrawNow();
       
   771     }
       
   772     
       
   773 
       
   774 //=============================================================================
       
   775 void CImageEditorRedEyeReductionControl::NaviDown()
       
   776 {
       
   777     switch (iState) 
       
   778     {
       
   779     case ERedEyeReductionStateMoveCrosshair:
       
   780         {
       
   781             iY += (KPosParamStep * iNaviStepMultiplier);
       
   782             if (iY > KPosParamMax)
       
   783             {
       
   784                 iY = KPosParamMax;
       
   785             }
       
   786             break;
       
   787         }
       
   788     case ERedEyeReductionStateResizeSelection:
       
   789         {
       
   790             iR -= (KRadiusParamStep * iNaviStepMultiplier);
       
   791             if (iR < KRadiusParamMin)
       
   792             {
       
   793                 iR = KRadiusParamMin;
       
   794             }
       
   795             break;
       
   796         }
       
   797     default:
       
   798         {
       
   799             ASSERT( EFalse );
       
   800             break;
       
   801         }
       
   802     }
       
   803 }
       
   804 
       
   805 //=============================================================================
       
   806 void CImageEditorRedEyeReductionControl::NaviUp()
       
   807 {
       
   808     switch (iState) 
       
   809     {
       
   810     case ERedEyeReductionStateMoveCrosshair:
       
   811         {
       
   812             iY -= (KPosParamStep * iNaviStepMultiplier);
       
   813             if (iY < KPosParamMin)
       
   814             {
       
   815                 iY = KPosParamMin;
       
   816             }
       
   817             break;
       
   818         }
       
   819     case ERedEyeReductionStateResizeSelection:
       
   820         {
       
   821             iR += (KRadiusParamStep * iNaviStepMultiplier);
       
   822             if (iR > KRadiusParamMax)
       
   823             {
       
   824                 iR = KRadiusParamMax;
       
   825             }
       
   826             break;
       
   827         }
       
   828     default:
       
   829         {
       
   830             break;
       
   831         } 
       
   832     }
       
   833 }
       
   834 
       
   835 //=============================================================================
       
   836 void CImageEditorRedEyeReductionControl::NaviRight()
       
   837 {
       
   838     switch (iState) 
       
   839     {
       
   840 	case ERedEyeReductionStateMoveCrosshair:
       
   841         {
       
   842             iX += (KPosParamStep * iNaviStepMultiplier);
       
   843             if (iX > KPosParamMax)
       
   844             {
       
   845                 iX = KPosParamMax;
       
   846             }
       
   847             break;
       
   848         }
       
   849 	case ERedEyeReductionStateResizeSelection:
       
   850         {
       
   851             iR += (KRadiusParamStep * iNaviStepMultiplier);
       
   852             if (iR > KRadiusParamMax)
       
   853             {
       
   854                 iR = KRadiusParamMax;
       
   855             }
       
   856             break;
       
   857         }
       
   858 	default:
       
   859         {
       
   860             break;
       
   861         }
       
   862     }
       
   863 }
       
   864 
       
   865 //=============================================================================
       
   866 void CImageEditorRedEyeReductionControl::NaviLeft()
       
   867 {
       
   868     switch (iState) 
       
   869     {
       
   870     case ERedEyeReductionStateMoveCrosshair:
       
   871         {
       
   872             iX -= (KPosParamStep * iNaviStepMultiplier);
       
   873             if (iX < KPosParamMin)
       
   874             {
       
   875                 iX = KPosParamMin;
       
   876             }
       
   877     	    break;
       
   878         }
       
   879     case ERedEyeReductionStateResizeSelection:
       
   880         {
       
   881             iR -= (KRadiusParamStep * iNaviStepMultiplier);
       
   882             if (iR < KRadiusParamMin)
       
   883             {
       
   884                 iR = KRadiusParamMin;
       
   885             }
       
   886             break;
       
   887         }
       
   888     default:
       
   889         {
       
   890     	    break;
       
   891         }
       
   892     }
       
   893 }
       
   894 
       
   895 //=============================================================================
       
   896 void CImageEditorRedEyeReductionControl::KeyOkL()
       
   897 {
       
   898     switch (iState) 
       
   899     {
       
   900     case ERedEyeReductionStateMoveCrosshair:
       
   901         {
       
   902             ToResizeStateL();
       
   903             break;
       
   904         }
       
   905     case ERedEyeReductionStateResizeSelection:
       
   906         {
       
   907             if ( iUndoArray.Count() > 0)
       
   908             {
       
   909 			    AddFilterToEngineL();
       
   910             }
       
   911 			else
       
   912 			{
       
   913 
       
   914                 // Update the filter parameters
       
   915                 ComputeParams();
       
   916 
       
   917                 // Store coodinates
       
   918                 iUndoArray.Append( iRedEyeRect );
       
   919 
       
   920 				// Render 
       
   921 				iEditorView->HandleCommandL (EImageEditorCmdRender);
       
   922 			}
       
   923 
       
   924 			
       
   925 #ifdef __TOUCH_ONLY_DEVICE_RER_PLUGIN_ACTION__ 
       
   926             // Loop only inside Resize state in touch-only devices
       
   927             ToResizeStateL();            
       
   928 
       
   929 #else
       
   930             
       
   931             // Go back to move state (non-touch)                
       
   932             ToMoveStateL();
       
   933 #endif                
       
   934 			                          
       
   935             break;
       
   936         }
       
   937 
       
   938     case ERedEyeReductionStateDone:
       
   939         {
       
   940             if ( iUndoArray.Count() > 0)
       
   941             {
       
   942 			    AddFilterToEngineL();
       
   943             }
       
   944 			else
       
   945             {            	
       
   946                 // Update the filter parameters
       
   947                 ComputeParams();
       
   948 
       
   949                 // Store coodinates
       
   950                 iUndoArray.Append( iRedEyeRect );
       
   951                                 
       
   952                 // Render 
       
   953             	iEditorView->HandleCommandL (EImageEditorCmdRender);
       
   954 			
       
   955 			}
       
   956             break;
       
   957         }
       
   958 
       
   959     default:
       
   960         {
       
   961             break;
       
   962         }
       
   963     }
       
   964 }
       
   965 
       
   966 //=============================================================================
       
   967 void CImageEditorRedEyeReductionControl::CancelPluginL()
       
   968 {
       
   969     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::CancelPluginL" );
       
   970 
       
   971     iState = ERedEyeReductionStateMin;
       
   972 
       
   973     // Undo all the filters exept for the first one,
       
   974     // which is cancelled by the framework.
       
   975     TInt count = iUndoArray.Count();
       
   976     while ( count > 1) 
       
   977     {
       
   978         iEditorView->HandleCommandL (EImageEditorUndoFilter);
       
   979         count--;
       
   980     }
       
   981 
       
   982     iEditorView->HandleCommandL (EImageEditorCancelPlugin);
       
   983 }
       
   984 
       
   985 //=============================================================================
       
   986 void CImageEditorRedEyeReductionControl::ToMoveStateL()
       
   987 {
       
   988 	LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::ToMoveState" );
       
   989 
       
   990 	// Stop dancing antz timer
       
   991 	if (iTimer)
       
   992 	{
       
   993 		iTimer->Cancel();
       
   994 	}
       
   995 
       
   996     // Update navi pane text
       
   997     iState = ERedEyeReductionStateMoveCrosshair;
       
   998     iNaviPaneText.Copy ( iItem->Parameters()[KMoveSelectionIndex] );
       
   999     iEditorView->HandleCommandL (EImageEditorUpdateNavipane);
       
  1000     // Update softkeys
       
  1001     iEditorView->HandleCommandL (EImageEditorUpdateSoftkeys);
       
  1002 
       
  1003 	ShowTooltip();
       
  1004 }
       
  1005 
       
  1006 //=============================================================================
       
  1007 void CImageEditorRedEyeReductionControl::ToResizeStateL()
       
  1008 {
       
  1009 	LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::ToResizeState" );
       
  1010 
       
  1011     // Start the timer
       
  1012     StartDancingAntzTimer();
       
  1013 
       
  1014     // Reset the selection radius
       
  1015     iR = KRadiusParamDef;
       
  1016 
       
  1017     // Update navi pane text
       
  1018     iState = ERedEyeReductionStateResizeSelection;
       
  1019     iNaviPaneText.Copy ( iItem->Parameters()[KResizeSelectionIndex] );
       
  1020     iEditorView->HandleCommandL (EImageEditorUpdateNavipane);
       
  1021 
       
  1022     // Update softkeys
       
  1023     iEditorView->HandleCommandL (EImageEditorUpdateSoftkeys);
       
  1024 
       
  1025 	ShowTooltip();
       
  1026 }
       
  1027 
       
  1028 //=============================================================================
       
  1029 TPoint CImageEditorRedEyeReductionControl::CursorLocation() const
       
  1030 {
       
  1031     __ASSERT_ALWAYS( iVisibleImageRectPrev, User::Panic(KComponentName, KErrNotReady) );
       
  1032 	TInt x = (TInt) (iX * (iVisibleImageRectPrev->Width())) + iVisibleImageRectPrev->iTl.iX;
       
  1033 	TInt y = (TInt) (iY * (iVisibleImageRectPrev->Height())) + iVisibleImageRectPrev->iTl.iY;
       
  1034     return TPoint( x, y );
       
  1035 }
       
  1036 
       
  1037 //=============================================================================
       
  1038 TRect CImageEditorRedEyeReductionControl::SelectionRect( const TPoint& aCenter ) const
       
  1039 {
       
  1040     __ASSERT_ALWAYS( iVisibleImageRectPrev, User::Panic(KComponentName, KErrNotReady) );
       
  1041 
       
  1042     // Radius iR is relative to the real image's x dimension.
       
  1043     // To obtain a circe, y-dimenson must be scaled accordingly.
       
  1044     TInt vpWidth = (iVisibleImageRect->iBr.iX - iVisibleImageRect->iTl.iX);
       
  1045     TInt vpHeight = (iVisibleImageRect->iBr.iY - iVisibleImageRect->iTl.iY);
       
  1046     TReal xyRatio = (TReal) vpHeight / vpWidth;
       
  1047 
       
  1048     //  Compute rectangle inside the image area
       
  1049     TInt width = iVisibleImageRectPrev->Width();
       
  1050     TInt height = iVisibleImageRectPrev->Height();
       
  1051 
       
  1052     TInt ulc = aCenter.iX - (TInt)( iR * width + 0.5 );           // upper left corner x
       
  1053     TInt ulr = aCenter.iY - (TInt)( iR * height / xyRatio + 0.5); // upper left corner y
       
  1054     TInt lrc = aCenter.iX + (TInt)( iR * width + 0.5 );           // lower right corner x
       
  1055     TInt lrr = aCenter.iY + (TInt)( iR * height / xyRatio + 0.5); // lower right corner y
       
  1056 
       
  1057     return TRect ( ulc, ulr, lrc, lrr );
       
  1058 }
       
  1059 
       
  1060 //=============================================================================
       
  1061 void CImageEditorRedEyeReductionControl::ComputeParams()
       
  1062 {
       
  1063     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::ComputeParams()" );
       
  1064 
       
  1065     __ASSERT_ALWAYS( iVisibleImageRect, User::Panic(KComponentName, KErrNotReady) );
       
  1066 
       
  1067     // Compute the coordinates
       
  1068 
       
  1069     TInt vpWidth = iVisibleImageRect->iBr.iX - iVisibleImageRect->iTl.iX;
       
  1070     TInt vpHeight = iVisibleImageRect->iBr.iY - iVisibleImageRect->iTl.iY;
       
  1071 
       
  1072     TInt r      = (TInt) (iR * vpWidth + 0.5);
       
  1073     TInt ulc    = (TInt) (iX * vpWidth + 0.5 ) - r;
       
  1074     TInt ulr    = (TInt) (iY * vpHeight + 0.5 ) - r;
       
  1075     TInt side   = (TInt) (2 * iR * vpWidth + 0.5);
       
  1076 
       
  1077     // Set the filter parameters.
       
  1078     // The coordinates iX and iR are relative to the viewport image,
       
  1079     // whereas the filter parameters are relative to the source image.
       
  1080    	iRedEyeRect.iTl.iX = iVisibleImageRect->iTl.iX + ulc;
       
  1081     iRedEyeRect.iTl.iY = iVisibleImageRect->iTl.iY + ulr;
       
  1082     iRedEyeRect.iBr.iX = iRedEyeRect.iTl.iX + side;
       
  1083     iRedEyeRect.iBr.iY = iRedEyeRect.iTl.iY + side;
       
  1084 
       
  1085     iReadyToRender = ETrue;   
       
  1086 }
       
  1087 
       
  1088 //=============================================================================
       
  1089 void CImageEditorRedEyeReductionControl::AddFilterToEngineL()
       
  1090 {
       
  1091     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::AddFilterToEngineL" );
       
  1092 
       
  1093     // Update the filter parameters
       
  1094     ComputeParams();
       
  1095 
       
  1096     // Store coodinates for undo
       
  1097     iUndoArray.Append( iRedEyeRect );
       
  1098 
       
  1099    	// Force adding the filter to the engine. This includes setting the undo point.
       
  1100 	iEditorView->HandleCommandL (EImageEditorAddFilterToEngine);
       
  1101 	iEditorView->HandleCommandL (EImageEditorStoreParameters);
       
  1102 
       
  1103     // Render 
       
  1104 	iEditorView->HandleCommandL (EImageEditorCmdRender);
       
  1105 }
       
  1106 
       
  1107 //=============================================================================
       
  1108 void CImageEditorRedEyeReductionControl::StartDancingAntzTimer()
       
  1109 {
       
  1110     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::StartDancingAntzTimer()" );
       
  1111 
       
  1112     iNaviStepMultiplier = KDefaultSmallNavigationStepMultiplier;
       
  1113 
       
  1114 	if (iTimer)
       
  1115 	{
       
  1116         iTimer->Cancel();
       
  1117 		iTimer->Start(
       
  1118 			TTimeIntervalMicroSeconds32 (KDancingAntzTimerDelayInMicroseconds),
       
  1119 			TTimeIntervalMicroSeconds32 (KDancingAntzTimerIntervalInMicroseconds),
       
  1120 			TCallBack (DancingAntzCallback, this)
       
  1121 			);
       
  1122 	}
       
  1123 }
       
  1124 
       
  1125 //=============================================================================
       
  1126 void CImageEditorRedEyeReductionControl::StartFastKeyTimer()
       
  1127 {
       
  1128     LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::StartFastKeyTimer()" );
       
  1129 
       
  1130     iNaviStepMultiplier = KDefaultSmallNavigationStepMultiplier;
       
  1131     iTickCount = 0;
       
  1132 
       
  1133 	if (iTimer)
       
  1134 	{
       
  1135 		iTimer->Cancel();
       
  1136 		iTimer->Start(
       
  1137 			TTimeIntervalMicroSeconds32 (KRedEyeFastKeyTimerDelayInMicroseconds),
       
  1138 			TTimeIntervalMicroSeconds32 (KRedEyeFastKeyTimerIntervalInMicroseconds),
       
  1139 			TCallBack (FastKeyCallback, this)
       
  1140 			);
       
  1141 	}
       
  1142 }
       
  1143 
       
  1144 //=============================================================================
       
  1145 void CImageEditorRedEyeReductionControl::OnDancingAntzCallBack()
       
  1146 {
       
  1147 	iAntFlag = !iAntFlag;
       
  1148 	ActivateGc();
       
  1149 	DrawDancingAntz (Rect());
       
  1150 	DeactivateGc();
       
  1151 }
       
  1152 
       
  1153 //=============================================================================
       
  1154 void CImageEditorRedEyeReductionControl::OnFastKeyCallBackL()
       
  1155 {
       
  1156 #ifdef VERBOSE
       
  1157     LOGFMT2( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::OnFastKeyCallBackL: iNaviStepMultiplier: %d, iTickCount: %d", iNaviStepMultiplier, iTickCount );
       
  1158 #endif
       
  1159 
       
  1160     if (iTickCount > KRedEyeFastKeyTimerMultiplyThresholdInTicks)
       
  1161     {
       
  1162         iNaviStepMultiplier = KRedEyeBigNavigationStepMultiplier;
       
  1163         LOG( KRedEyeReductionPluginLogFile, "CImageEditorRedEyeReductionControl::OnFastKeyCallBackL: switching to big steps" );
       
  1164     }
       
  1165     else
       
  1166     {
       
  1167         iTickCount++;
       
  1168     }
       
  1169 
       
  1170     iHandleEventKeys = EFalse;
       
  1171 
       
  1172 	switch (iPressedKeyScanCode)
       
  1173 	{
       
  1174 		case EStdKeyDownArrow:
       
  1175 		{
       
  1176             NaviDown();
       
  1177 			break;
       
  1178 		}
       
  1179 		case EStdKeyUpArrow:
       
  1180 		{
       
  1181             NaviUp();
       
  1182 			break;
       
  1183 		}
       
  1184 		case EStdKeyLeftArrow:
       
  1185 		{
       
  1186 			NaviLeft();
       
  1187 			break;
       
  1188 		}
       
  1189 		case EStdKeyRightArrow:
       
  1190 		{
       
  1191             NaviRight();
       
  1192 			break;
       
  1193 		}
       
  1194         default:
       
  1195             break;
       
  1196 	}
       
  1197 	DrawNow();
       
  1198 }
       
  1199 
       
  1200 //=============================================================================
       
  1201 TBool CImageEditorRedEyeReductionControl::IsReadyToRender() const
       
  1202 {
       
  1203     return iReadyToRender;
       
  1204 }
       
  1205 
       
  1206 //=============================================================================
       
  1207 void CImageEditorRedEyeReductionControl::GetHelpContext(TCoeHelpContext& aContext) const
       
  1208 {
       
  1209     aContext.iMajor = TUid::Uid(UID_IMAGE_EDITOR);
       
  1210     aContext.iContext = KSIE_HLP_REDEYE;
       
  1211 }
       
  1212 
       
  1213 //=============================================================================
       
  1214 void CImageEditorRedEyeReductionControl::ClipPosition()
       
  1215 {
       
  1216     if (iX < KPosParamMin)
       
  1217     {
       
  1218         iX = KPosParamMin;
       
  1219     }
       
  1220     else if (iX > KPosParamMax)
       
  1221     {
       
  1222         iX = KPosParamMax;
       
  1223     }
       
  1224 
       
  1225     if (iY < KPosParamMin)
       
  1226     {
       
  1227         iY = KPosParamMin;
       
  1228     }
       
  1229     else if (iY > KPosParamMax)
       
  1230     {
       
  1231         iY = KPosParamMax;
       
  1232     }
       
  1233 }
       
  1234 
       
  1235 //=============================================================================
       
  1236 void CImageEditorRedEyeReductionControl::HandlePointerEventL(
       
  1237                                             const TPointerEvent &aPointerEvent)
       
  1238     {        
       
  1239     if( AknLayoutUtils::PenEnabled() )
       
  1240 		{		
       
  1241 		TBool drawNow ( EFalse );
       
  1242 		switch( aPointerEvent.iType )
       
  1243 			{
       
  1244 			case TPointerEvent::EButton1Down:
       
  1245 				{
       
  1246 				iPopupController->HideInfoPopupNote();
       
  1247 			    // Enable dragging if in cursor area tapped 
       
  1248 			    // (both move and resize cases)
       
  1249 			    if ( CursorTapped( aPointerEvent.iPosition ) )
       
  1250 			        {			        
       
  1251 			        iCursorDragEnabled = ETrue;
       
  1252 			        drawNow = EFalse;
       
  1253 			        }
       
  1254 			    else if ( iState == ERedEyeReductionStateResizeSelection )
       
  1255 			        {			        
       
  1256 			        // Tapping outside cursor area just stores the pointer
       
  1257 			        // position
       
  1258 			        if ( !CursorTapped( aPointerEvent.iPosition ) )
       
  1259 			            {
       
  1260 			            iPointerPosition = aPointerEvent.iPosition;
       
  1261 			            drawNow = EFalse;
       
  1262 			            }    
       
  1263 			        }
       
  1264 				
       
  1265 #ifdef RD_TACTILE_FEEDBACK
       
  1266 				if ( iTouchFeedBack )
       
  1267 					{
       
  1268 					iTouchFeedBack->InstantFeedback( ETouchFeedbackBasic );
       
  1269 					RDebug::Printf( "ImageEditor::ImageEditorRedEyeReductionControl: ETouchFeedback" );
       
  1270 					}
       
  1271 #endif /* RD_TACTILE_FEEDBACK  */
       
  1272 			    
       
  1273 				break;
       
  1274 				}
       
  1275 			case TPointerEvent::EDrag:
       
  1276 				{
       
  1277 				// Sets the new cursor position when drag is enabled
       
  1278 				// (i.e. EButton1Down has happened in cursor area)
       
  1279                 if ( ( iState == ERedEyeReductionStateMoveCrosshair || 
       
  1280                        iState ==ERedEyeReductionStateResizeSelection ) 
       
  1281                        && iCursorDragEnabled )
       
  1282                     {
       
  1283                     SetCursorPosition( aPointerEvent.iPosition );
       
  1284 			    	// prevents user to move cursor outside image area
       
  1285 			    	ClipPosition();	
       
  1286 			    	drawNow = ETrue;	    
       
  1287                     }
       
  1288                     
       
  1289                 // Selection cursor can be grown or made smaller moving
       
  1290                 // pen up and down outside the cursor area
       
  1291                 if ( iState == ERedEyeReductionStateResizeSelection && 
       
  1292                      !iCursorDragEnabled )
       
  1293                     {                    
       
  1294                     if ( CalculateResize( iPointerPosition, 
       
  1295 				                          aPointerEvent.iPosition ) )
       
  1296                         {
       
  1297                         iPointerPosition = aPointerEvent.iPosition;
       
  1298                         drawNow = ETrue;
       
  1299                         }
       
  1300                     else
       
  1301                         {
       
  1302                         drawNow = EFalse;
       
  1303                         }    
       
  1304                     }    
       
  1305                                                             
       
  1306 				break;		
       
  1307 				}
       
  1308 			case TPointerEvent::EButton1Up:
       
  1309 				{
       
  1310 				// Sets crosshair cursor to a new position
       
  1311 				if ( iState == ERedEyeReductionStateMoveCrosshair )
       
  1312 				    {
       
  1313 				    SetCursorPosition( aPointerEvent.iPosition );
       
  1314 			    	ClipPosition();
       
  1315 			    	drawNow = ETrue;
       
  1316 				    }
       
  1317 			
       
  1318 				ShowTooltip();
       
  1319 				    
       
  1320 				iCursorDragEnabled = EFalse;    
       
  1321 				break;
       
  1322 				}
       
  1323 						
       
  1324 			default:
       
  1325 				{
       
  1326 				break;	
       
  1327 				}	
       
  1328 			}
       
  1329 	
       
  1330 		CCoeControl::HandlePointerEventL( aPointerEvent );
       
  1331     
       
  1332         if ( drawNow ) 
       
  1333             {
       
  1334             DrawNow();    
       
  1335             }	
       
  1336 		}
       
  1337     }
       
  1338 
       
  1339 //=============================================================================    
       
  1340 void CImageEditorRedEyeReductionControl::SetCursorPosition( TPoint aNewPosition )
       
  1341     {    
       
  1342     //Set new x value
       
  1343     iX = TReal( aNewPosition.iX - iVisibleImageRectPrev->iTl.iX ) /
       
  1344 			  ( iVisibleImageRectPrev->iBr.iX - iVisibleImageRectPrev->iTl.iX );
       
  1345     
       
  1346     //Set new y value
       
  1347     iY = TReal( aNewPosition.iY - iVisibleImageRectPrev->iTl.iY  ) /
       
  1348 			  ( iVisibleImageRectPrev->iBr.iY - iVisibleImageRectPrev->iTl.iY ); 
       
  1349     }
       
  1350 
       
  1351 
       
  1352 //=============================================================================    
       
  1353 TRect CImageEditorRedEyeReductionControl::CrossHairCursorRect() const
       
  1354     {   
       
  1355      
       
  1356     TSize chSize = iCrossHair->SizeInPixels();
       
  1357 	TPoint center = CursorLocation();
       
  1358     TPoint topLeftCorner(center.iX - (chSize.iWidth >> 1), 
       
  1359                          center.iY - (chSize.iHeight >> 1));
       
  1360     
       
  1361     TRect moveCursorRect( topLeftCorner, chSize );
       
  1362     
       
  1363     return moveCursorRect;
       
  1364     
       
  1365     }
       
  1366     
       
  1367 //=============================================================================
       
  1368 TBool CImageEditorRedEyeReductionControl::CursorTapped( TPoint aTappedPosition ) const
       
  1369     {
       
  1370     TBool cursorTapped( EFalse );
       
  1371     TRect cursorRect;
       
  1372     
       
  1373     if ( iState == ERedEyeReductionStateMoveCrosshair )
       
  1374         {
       
  1375 		cursorRect = CrossHairCursorRect();
       
  1376 		
       
  1377 		TPoint newTLCorner = TPoint( cursorRect.iTl.iX - ( cursorRect.Width() / 2 ),
       
  1378 		                             cursorRect.iTl.iY - ( cursorRect.Height() / 2 ) );		                             
       
  1379 		TPoint newBRCorner = TPoint( cursorRect.iBr.iX + ( cursorRect.Width() / 2 ),
       
  1380 		                             cursorRect.iBr.iY + ( cursorRect.Height() / 2 ));
       
  1381 		
       
  1382 		// Make tappable rect double sized to crosshair rect
       
  1383 		TRect doubleCursorRect = TRect( newTLCorner, newBRCorner );
       
  1384 		
       
  1385 		cursorTapped = doubleCursorRect.Contains( aTappedPosition );
       
  1386 		}
       
  1387 	else if ( iState == ERedEyeReductionStateResizeSelection )
       
  1388 	    {
       
  1389 		cursorRect = SelectionRect( CursorLocation() );
       
  1390 		cursorTapped = cursorRect.Contains( aTappedPosition );
       
  1391 		}
       
  1392 		
       
  1393     return cursorTapped;
       
  1394     } 
       
  1395 
       
  1396 //=============================================================================    
       
  1397 void CImageEditorRedEyeReductionControl::ShowTooltip()
       
  1398     {   
       
  1399     iPopupController->HideInfoPopupNote();
       
  1400     
       
  1401     if ( iState == ERedEyeReductionStateMoveCrosshair )
       
  1402         { 
       
  1403         TPoint center = CursorLocation();
       
  1404         SDrawUtils::ShowToolTip( iPopupController,
       
  1405                                  this,
       
  1406                                  center,
       
  1407                                  EHLeftVBottom,
       
  1408                                  *iTooltipLocate );
       
  1409         }
       
  1410     else if ( iState == ERedEyeReductionStateResizeSelection )
       
  1411         {
       
  1412         TRect circleRect ( SelectionRect( CursorLocation() ) );
       
  1413         TPoint center( circleRect.Center() );
       
  1414         
       
  1415         SDrawUtils::ShowToolTip( iPopupController,
       
  1416                                  this,
       
  1417                                  center,
       
  1418                                  EHLeftVBottom,
       
  1419                                  *iTooltipOutline );
       
  1420         }
       
  1421     }
       
  1422 
       
  1423 //=============================================================================
       
  1424 TBool CImageEditorRedEyeReductionControl::CalculateResize( TPoint aStartPoint, 
       
  1425                                                   TPoint aEndPoint )
       
  1426     {
       
  1427     // Whether bubble is resized in this function or not
       
  1428     TBool radiusChanged( EFalse );
       
  1429     // Store old scale value
       
  1430     TReal oldRadius = iR;
       
  1431     TReal changeThreshold( 0.001 );  
       
  1432     
       
  1433     // Get system parameters
       
  1434     TRect visibleImageRectPrev( iSysPars->VisibleImageRectPrev() );
       
  1435             
       
  1436     // Compute change on the screen
       
  1437     TInt deltaX = aEndPoint.iX - aStartPoint.iX;
       
  1438     TInt deltaY = aEndPoint.iY - aStartPoint.iY;
       
  1439    	
       
  1440    	// Use bigger dimension
       
  1441 	TInt maxChangeInPixels;
       
  1442 	if ( visibleImageRectPrev.Height() > visibleImageRectPrev.Width() )
       
  1443 	    {
       
  1444 	    maxChangeInPixels = visibleImageRectPrev.Height();
       
  1445 	    }
       
  1446 	else
       
  1447 	    {
       
  1448 	    maxChangeInPixels = visibleImageRectPrev.Width();
       
  1449 	    }
       
  1450 	  
       
  1451 	TInt oneStepInPixels =  maxChangeInPixels / KTouchScaleMaxStepCount;
       
  1452 	TReal scaleStep = ( KRadiusParamMax - KRadiusParamMin ) / KTouchScaleMaxStepCount;
       
  1453 
       
  1454     // Relates to second and fourth corners. Defines how steep/gentle the 
       
  1455     // moving angle has to be in order to scale.
       
  1456     TInt slopeAngleFactor = 3;
       
  1457     
       
  1458     // The first quarter (movement towards upper-right corner)
       
  1459     if( ( deltaX > 0 && deltaY <= 0 ) || ( deltaX >= 0 && deltaY < 0 ) )
       
  1460         {
       
  1461         // use bigger value
       
  1462         if (Abs( deltaX ) >= Abs( deltaY) )
       
  1463             {
       
  1464             iR += scaleStep * ( Abs( deltaX ) / oneStepInPixels );
       
  1465             }
       
  1466         else
       
  1467             {
       
  1468             iR += scaleStep * ( Abs( deltaY ) / oneStepInPixels );
       
  1469             }				                             
       
  1470         }
       
  1471     // The second (movement towards lower-right corner)  	
       
  1472     else if( ( deltaX > 0 && deltaY >= 0 ) || ( deltaX >= 0 && deltaY > 0 ) )
       
  1473         {
       
  1474         if( deltaX > slopeAngleFactor * deltaY )
       
  1475             {			                
       
  1476 	        iR += scaleStep * ( Abs( deltaX ) / oneStepInPixels );    
       
  1477             }
       
  1478 	        			               
       
  1479         else if ( slopeAngleFactor * deltaX < deltaY )
       
  1480             {			              
       
  1481 	        iR -= scaleStep * ( Abs( deltaY ) / oneStepInPixels ); 
       
  1482 	        }
       
  1483         }    
       
  1484     // The third (movement towards lower-left corner)
       
  1485     else if( ( deltaX < 0 && deltaY >= 0 ) || ( deltaX <= 0 && deltaY > 0 ) )
       
  1486         {
       
  1487         if (Abs( deltaX ) >= Abs( deltaY) )
       
  1488             {
       
  1489             iR -= scaleStep * ( Abs( deltaX ) / oneStepInPixels );    
       
  1490             }
       
  1491         else
       
  1492             {
       
  1493             iR -= scaleStep * ( Abs( deltaY ) / oneStepInPixels ); 
       
  1494             }
       
  1495         }
       
  1496     // The fourth (movement towards upper-left corner)
       
  1497     else if( ( deltaX < 0 && deltaY <= 0 ) || ( deltaX <= 0 && deltaY < 0 ) )
       
  1498         {
       
  1499         if( slopeAngleFactor * Abs( deltaX ) < Abs( deltaY ) )
       
  1500             {
       
  1501             iR += scaleStep * ( Abs( deltaY ) / oneStepInPixels ); 
       
  1502             }
       
  1503         else if ( Abs( deltaX ) > slopeAngleFactor * Abs( deltaY ) )
       
  1504             {
       
  1505             iR -= scaleStep * ( Abs( deltaX ) / oneStepInPixels );    
       
  1506 	        }
       
  1507         }
       
  1508     
       
  1509     // Check the limits        
       
  1510     if (iR > KRadiusParamMax)
       
  1511         {
       
  1512         iR = KRadiusParamMax;
       
  1513         radiusChanged = ETrue;
       
  1514         }
       
  1515     
       
  1516     if (iR < KRadiusParamMin)
       
  1517         {
       
  1518         iR = KRadiusParamMin;
       
  1519         radiusChanged = ETrue;
       
  1520         }
       
  1521                                 
       
  1522     if ( Abs( oldRadius - iR ) > changeThreshold )
       
  1523         {
       
  1524         radiusChanged = ETrue;
       
  1525         }
       
  1526         
       
  1527     return radiusChanged;
       
  1528     
       
  1529     }    
       
  1530 // End of File