|
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 |