photosgallery/slideshow/engine/effectsrc/shwzoomandpanlayout.cpp
changeset 0 4e91876724a2
child 14 ce1c7ad1f18b
equal deleted inserted replaced
-1:000000000000 0:4e91876724a2
       
     1 /*
       
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "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 *
       
    14 * Description:    Layout that performs crossfade
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 //  Include Files
       
    22 #include "shwzoomandpanlayout.h"
       
    23 #include <e32math.h>
       
    24 
       
    25 #include <uiacceltk/HuiCurvePath.h>
       
    26 
       
    27 #include <glxlog.h>
       
    28 
       
    29 #include "shwconstants.h"
       
    30 #include "shwgeometryutilities.h"
       
    31 
       
    32 using namespace NShwSlideshow;
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // Constructor
       
    36 // -----------------------------------------------------------------------------
       
    37 TShwZoomAndPanLayout::TShwZoomAndPanLayout()
       
    38 	: iScreenSize( 0, 0 ),
       
    39 	iImageSize(	0, 0 ),
       
    40 	iPanningCurve( NULL ) // T-class so need to set value
       
    41 	{
       
    42 	__DEBUG_ONLY( _iName = _L("TShwZoomAndPanLayout") );
       
    43 	// default values
       
    44 	// curve style is linear
       
    45 	iCurvePosition.SetStyle( EAlfTimedValueStyleLinear );
       
    46 	// set zoom style to sine so it accelerates and decelerates
       
    47 	iZoomedSize.SetStyle( EAlfTimedValueStyleSineWave );
       
    48 	}
       
    49 
       
    50 // -----------------------------------------------------------------------------
       
    51 // Destructor
       
    52 // -----------------------------------------------------------------------------
       
    53 TShwZoomAndPanLayout::~TShwZoomAndPanLayout()
       
    54 	{
       
    55 	// Do nothing
       
    56 	}
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // SetSizes
       
    60 // -----------------------------------------------------------------------------
       
    61 TReal32 TShwZoomAndPanLayout::SetSizes(
       
    62     TSize aScreenSize, TSize aImageSize, TSize aMaximumSize )
       
    63 	{
       
    64 	GLX_LOG_INFO( "TShwZoomAndPanLayout::SetSizes" );
       
    65 	// set the size from TSize (integer) to THuiRealSize (float)
       
    66 	iScreenSize.iWidth = aScreenSize.iWidth;
       
    67 	iScreenSize.iHeight = aScreenSize.iHeight;
       
    68 	iImageSize.iWidth = aImageSize.iWidth;
       
    69 	iImageSize.iHeight = aImageSize.iHeight;
       
    70 	// recalculate min and max size for zoom
       
    71 	CalculateMinAndMaxSize( aMaximumSize );
       
    72 	// calculate zoom factor for iHeight, iWidth is same as aspect ratio is kept
       
    73 	// maximum per minimum
       
    74 	TReal32 zoomFactor = iMaximumSize.iHeight / iMinimumSize.iHeight;
       
    75 	// return zoom factor
       
    76 	return zoomFactor;
       
    77 	}
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // SetPanningCurve
       
    81 // -----------------------------------------------------------------------------
       
    82 void TShwZoomAndPanLayout::SetPanningCurve( CAlfCurvePath* aCurve )
       
    83 	{
       
    84 	iPanningCurve = aCurve;
       
    85 	}
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // MaximumSize
       
    89 // -----------------------------------------------------------------------------
       
    90 TSize TShwZoomAndPanLayout::MaximumSize()
       
    91     {
       
    92     return iMaximumSize;
       
    93     }
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // ResetSizeToMinimum
       
    97 // -----------------------------------------------------------------------------
       
    98 void TShwZoomAndPanLayout::ResetSizeToMinimum()
       
    99 	{
       
   100 	GLX_LOG_INFO( "TShwZoomAndPanLayout::ResetSizeToMinimum" );
       
   101 	// set initial size to minimum size
       
   102 //	iZoomedSize.Set( iMinimumSize );
       
   103 	}
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // StartZoom
       
   107 // -----------------------------------------------------------------------------
       
   108 void TShwZoomAndPanLayout::StartZoom(
       
   109 	TZoomDirection aZoomDirection, TInt aDuration )
       
   110 	{
       
   111 	GLX_LOG_INFO1(
       
   112         "TShwZoomAndPanLayout::StartZoom( %d )", aDuration );
       
   113 
       
   114 	// remember the zoom direction
       
   115 	iZoomDirection = aZoomDirection;
       
   116 	// remember also the zoom duration
       
   117 	iZoomDuration = aDuration;
       
   118 
       
   119 	// calculate curve position
       
   120 	TInt curveLength = 0;
       
   121 	// set curvelength, if we have curve
       
   122 	if( iPanningCurve )
       
   123 		{
       
   124 		curveLength = iPanningCurve->Length();
       
   125 		}
       
   126 
       
   127 	// default case is to run the first half of the curve
       
   128 	TInt curveStart = 0;
       
   129 	TInt curveEnd = curveLength  / 2;
       
   130 
       
   131 	// change the zoom according to direction
       
   132 	if( EZoomOut == aZoomDirection )
       
   133 		{
       
   134 		GLX_LOG_INFO2( 
       
   135 			"TShwZoomAndPanLayout:: Zooming out start(%.1f,%.1f)", 
       
   136 			iMaximumSize.iWidth, iMaximumSize.iHeight );
       
   137 		GLX_LOG_INFO2( 
       
   138 			"TShwZoomAndPanLayout:: Zooming out target(%.1f,%.1f)", 
       
   139 			iMinimumSize.iWidth, iMinimumSize.iHeight );
       
   140 		// zooming out so we start from maximum size
       
   141 		//iZoomedSize.Set( iMaximumSize );
       
   142 		// target is the minimum size
       
   143 	//	iZoomedSize.Set( iMinimumSize, aDuration );
       
   144 		// run the latter half of the curve
       
   145 		curveStart = curveLength / 2;
       
   146 		curveEnd = curveLength;
       
   147 		}
       
   148 	else // default case is EZoomIn
       
   149 		{
       
   150 		GLX_LOG_INFO2( 
       
   151 			"TShwZoomAndPanLayout:: Zooming in start(%.1f,%.1f)", 
       
   152 			iMinimumSize.iWidth, iMinimumSize.iHeight );
       
   153 		GLX_LOG_INFO2( 
       
   154 			"TShwZoomAndPanLayout:: Zooming in target(%.1f,%.1f)", 
       
   155 			iMaximumSize.iWidth, iMaximumSize.iHeight );
       
   156 		// zooming in so we start from minimum size
       
   157 //		iZoomedSize.Set( iMinimumSize );
       
   158 		// target is maximum size
       
   159 //		iZoomedSize.Set( iMaximumSize, aDuration );
       
   160 		}
       
   161 
       
   162 	// set position, if we have curve its either from start to half 
       
   163 	// or half to end and if we dont then its always 0
       
   164 	iCurvePosition.Set( curveStart );
       
   165 	iCurvePosition.Set( curveEnd, aDuration );
       
   166 	}
       
   167 
       
   168 // -----------------------------------------------------------------------------
       
   169 // Pause
       
   170 // -----------------------------------------------------------------------------
       
   171 TInt TShwZoomAndPanLayout::InvertZoom()
       
   172 	{
       
   173 	GLX_LOG_INFO( "TShwZoomAndPanLayout::InvertZoom" );
       
   174 	if( EZoomOut == iZoomDirection )
       
   175 		{
       
   176 		StartZoom( EZoomIn, iZoomDuration );
       
   177 		}
       
   178 	else
       
   179 		{
       
   180 		StartZoom( EZoomOut, iZoomDuration );
       
   181 		}
       
   182 	
       
   183 	return 0;
       
   184 	}
       
   185 
       
   186 // -----------------------------------------------------------------------------
       
   187 // Pause
       
   188 // -----------------------------------------------------------------------------
       
   189 void TShwZoomAndPanLayout::Pause()
       
   190 	{
       
   191 	GLX_LOG_INFO( "TShwZoomAndPanLayout::Pause" );
       
   192 	// pause size
       
   193 	iZoomedSize.Pause();
       
   194 	// pause curve position
       
   195 	iCurvePosition.Pause();
       
   196 	}
       
   197 
       
   198 // -----------------------------------------------------------------------------
       
   199 // Resume
       
   200 // -----------------------------------------------------------------------------
       
   201 void TShwZoomAndPanLayout::Resume()
       
   202 	{
       
   203 	GLX_LOG_INFO( "TShwZoomAndPanLayout::Resume" );
       
   204 	// resume size
       
   205 	iZoomedSize.Resume();
       
   206 	// resume pan curve
       
   207 	iCurvePosition.Resume();
       
   208 	}
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // DoSetLayoutValues
       
   212 // -----------------------------------------------------------------------------
       
   213 void TShwZoomAndPanLayout::DoSetLayoutValues( TGlxLayoutInfo& aInfo )
       
   214 	{
       
   215 	// calculate new x size, current value from zoomedsize
       
   216 	TReal32 x_size = iZoomedSize.iWidth.Now();
       
   217 	// calculate new y size, current value from zoomedsize
       
   218 	TReal32 y_size = iZoomedSize.iHeight.Now();
       
   219 
       
   220 	// ensure x is inside  maximum size and minimum size
       
   221     x_size = Min( x_size, iMaximumSize.iWidth );
       
   222     x_size = Max( x_size, iMinimumSize.iWidth );
       
   223 	// set x size, it is now inside the minimum and maximum
       
   224 	//aInfo.iSize.iX = x_size;
       
   225 
       
   226     // ensure y is inside  maximum size and minimum size
       
   227     y_size = Min( y_size, iMaximumSize.iHeight );
       
   228     y_size = Max( y_size, iMinimumSize.iHeight );
       
   229 	// set y size, it is now inside the minimum and maximum
       
   230 //	aInfo.iSize.iY = y_size;
       
   231 
       
   232 	// set position only if we have a panning curve, this enables the use of this
       
   233     // layout as only a zooming layout and then some other layout can define 
       
   234     // the position (as we dont overwrite 0,0 there...)
       
   235 	if( iPanningCurve )
       
   236 		{
       
   237 		// need to ensure that position does not make image 
       
   238 		// go outside the bounding box. We trust that the curve has 
       
   239 		// been calculated so that in 100% zoom it stays inside the image
       
   240 		// so the only thing needed is to ensure zoom keeps the image inside
       
   241 		// the box as well.
       
   242 		// this is done by scaling the position with the current 
       
   243 		// zoomfactor per maximum zoomfactor. The scalefactor is between
       
   244 		// 0 and 1; when size is minimum the scale is 0 and when size
       
   245 		// is maximum the scale is 1.
       
   246 		// If we are in minimum size, we cant do any panning and
       
   247 		// if we are in maximum size we can do the maximum pan.
       
   248 		// current zoomfactor is current height per the minimum height
       
   249 		// formula:
       
   250 		//         current.y - minimum.y
       
   251 		// scale = ---------------------
       
   252 		//         maximum.y - minimum.y
       
   253 		// and need to ensure maximum.y > minimum.y, otherwise scale becomes
       
   254 		// infinite
       
   255 		if( iMaximumSize.iHeight > iMinimumSize.iHeight )
       
   256 			{
       
   257 /*			TReal32 scale = ( aInfo.iSize.iY - iMinimumSize.iHeight ) /
       
   258 							( iMaximumSize.iHeight - iMinimumSize.iHeight );
       
   259 			// multiply the curve with scale
       
   260 			// set x position
       
   261 			aInfo.iPosition.iX = 
       
   262 				scale * iPanningCurve->MapValue( iCurvePosition.Now(), 0 );
       
   263 			// set y position
       
   264 			aInfo.iPosition.iY =
       
   265 				scale * iPanningCurve->MapValue( iCurvePosition.Now(), 1 );*/
       
   266 			}
       
   267 		else
       
   268 	        {
       
   269 	        // Panning curve defined but we either zoomed to screen size or
       
   270 	        // the image was smaller than or equal to screen size so
       
   271 	        // just set position to origo to see image centered on the screen
       
   272 		//	aInfo.iPosition.iX = 0;
       
   273 		//	aInfo.iPosition.iY = 0;
       
   274 	        }
       
   275 		}
       
   276 	}
       
   277 
       
   278 // -----------------------------------------------------------------------------
       
   279 // DoChanged
       
   280 // -----------------------------------------------------------------------------
       
   281 TBool TShwZoomAndPanLayout::DoChanged() const
       
   282 	{
       
   283 	TBool ret = EFalse;
       
   284 	if( iPanningCurve )
       
   285 		{
       
   286 //		ret = iPanningCurve->MappingFunctionChanged();
       
   287 		}
       
   288 	return iZoomedSize.Changed() || ret;
       
   289 	}
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // DoClearChanged
       
   293 // -----------------------------------------------------------------------------
       
   294 void TShwZoomAndPanLayout::DoClearChanged() 
       
   295 	{
       
   296 	iZoomedSize.ClearChanged();
       
   297 	if( iPanningCurve )
       
   298 		{
       
   299 //		iPanningCurve->MappingFunctionClearChanged();
       
   300 		}
       
   301 	}
       
   302 
       
   303 // -----------------------------------------------------------------------------
       
   304 // CalculateMinAndMaxSize
       
   305 // -----------------------------------------------------------------------------
       
   306 void TShwZoomAndPanLayout::CalculateMinAndMaxSize( TSize aMaximumSize )
       
   307 	{
       
   308     // use the namespace for coord utilities
       
   309     using namespace NShwGeometryUtilities;
       
   310 
       
   311     // set minimum size to be the image size
       
   312     iMinimumSize.iWidth = iImageSize.iWidth;
       
   313     iMinimumSize.iHeight = iImageSize.iHeight;
       
   314 
       
   315     // scale minimum size inside the screen
       
   316     FitToCoverBox( 
       
   317         iMinimumSize.iWidth, 
       
   318         iMinimumSize.iHeight, 
       
   319         iScreenSize.iWidth, 
       
   320         iScreenSize.iHeight );
       
   321 
       
   322     // check if the image is large enough for zooming
       
   323     TReal32 zoomFactor = 
       
   324         ( iImageSize.iWidth * iImageSize.iHeight ) / 
       
   325             ( iScreenSize.iWidth * iScreenSize.iHeight );
       
   326     // if combined zoom factor is big enough then zoom
       
   327     // so if image is for example half the width but double the height of screen
       
   328     // we dont zoom
       
   329     if( zoomFactor > KMinZoomAndPanFactor )
       
   330         {
       
   331         // the image should be zoomed, figure out if its
       
   332         // from screen size -> image size * KOptimalZoomAndPanFactor or
       
   333         // from screen size -> image size * KMaxZoomAndPanFactor
       
   334     	// set maximum size to image dimensions multiplied
       
   335     	// by KShwOptimalZoomAndPanFactor
       
   336     	// this defines how much we want the max zoom
       
   337     	// to be in optimal case
       
   338     	iMaximumSize.iWidth = iImageSize.iWidth * KOptimalZoomAndPanFactor;
       
   339     	iMaximumSize.iHeight = iImageSize.iHeight * KOptimalZoomAndPanFactor;
       
   340         // check if the image is large enough for zooming, 
       
   341         // only need to check either coordinate as aspect ratio is kept
       
   342         // Images between screen size and screen size * KMaxZoomAndPanFactor
       
   343     	// get zoomed between screen size and screen size * KMaxZoomAndPanFactor
       
   344         if( ( iMaximumSize.iWidth < iMinimumSize.iWidth * KMaxZoomAndPanFactor )||
       
   345             ( iMaximumSize.iHeight < iMinimumSize.iHeight * KMaxZoomAndPanFactor ) )
       
   346             {
       
   347             // image is too small from either dimension
       
   348             // so zoom from minimum size to Screen x KMaxZoomAndPanFactor
       
   349             FitToCoverBox( 
       
   350                 iMaximumSize.iWidth, 
       
   351                 iMaximumSize.iHeight,
       
   352                 iScreenSize.iWidth * KMaxZoomAndPanFactor,
       
   353                 iScreenSize.iHeight * KMaxZoomAndPanFactor );
       
   354             }
       
   355         // calculate maximum Width and Height for this image
       
   356         // the maximum thumbnailsize defines the maximum amount of pixels 
       
   357         // we should ever load. We need to adjust this box to have the
       
   358         // same aspect ratio of the image; so in short:
       
   359         //      same amount of pixels than maximum but aspect ratio of image
       
   360         TReal32 maxWidth = aMaximumSize.iWidth;
       
   361         TReal32 maxHeight = aMaximumSize.iHeight;
       
   362         // calculate the image size difference and take square root to get
       
   363         // multiplier for both width and height, ignore error
       
   364         //                    maximumWidth * maximumHeight
       
   365         // multiplier = sqrt( ---------------------------- )
       
   366         //                      imagewidth * imageheight 
       
   367         TReal64 multiplier;
       
   368         (void)Math::Sqrt( multiplier, 
       
   369             ( maxHeight * maxWidth ) / 
       
   370             ( iImageSize.iWidth * iImageSize.iHeight ) );
       
   371         // maxwidth = imagewidth * multiplier
       
   372         TReal32 maximumWidth = multiplier * iImageSize.iWidth;
       
   373         // maxheight = imageheight * multiplier
       
   374         TReal32 maximumHeight = multiplier * iImageSize.iHeight;
       
   375         // then fit the maximum size inside that box
       
   376         FitInsideBox( 
       
   377             iMaximumSize.iWidth, iMaximumSize.iHeight,
       
   378             maximumWidth, maximumHeight );
       
   379         }
       
   380     else
       
   381         {
       
   382         // not enough to zoom so just streth to screen size. 
       
   383         // set maximum to be minimum
       
   384         iMaximumSize.iWidth = iMinimumSize.iWidth;
       
   385         iMaximumSize.iHeight = iMinimumSize.iHeight;
       
   386         }
       
   387 
       
   388 	}
       
   389