Conversion to Apache 2.0 license
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-unmanaged / utc-Dali-ScrollViewEffect.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <iostream>
19
20 #include <stdlib.h>
21 #include <dali-toolkit-test-suite-utils.h>
22 #include <dali-toolkit/dali-toolkit.h>
23 #include <dali/integration-api/events/touch-event-integ.h>
24 #include <dali/integration-api/events/pan-gesture-event.h>
25
26
27 using namespace Dali;
28 using namespace Toolkit;
29
30 void dali_scroll_view_effect_startup(void)
31 {
32   test_return_value = TET_UNDEF;
33 }
34
35 void dali_scroll_view_effect_cleanup(void)
36 {
37   test_return_value = TET_PASS;
38 }
39
40 namespace
41 {
42
43 const int MILLISECONDS_PER_SECOND = 1000;
44 const int RENDER_FRAME_INTERVAL = 16;                           ///< Duration of each frame in ms. (at approx 60FPS)
45 const int RENDER_ANIMATION_TEST_DURATION_MS = 1000;             ///< 1000ms to test animation
46 const int RENDER_DELAY_SCROLL = 1000;                           ///< duration to wait for any scroll to complete.
47
48 /*
49  * Simulate time passed by.
50  *
51  * @note this will always process at least 1 frame (1/60 sec)
52  *
53  * @param application Test application instance
54  * @param duration Time to pass in milliseconds.
55  * @return The actual time passed in milliseconds
56  */
57 int Wait(ToolkitTestApplication& application, int duration = 0)
58 {
59   int time = 0;
60
61   for(int i = 0; i <= ( duration / RENDER_FRAME_INTERVAL); i++)
62   {
63     application.SendNotification();
64     application.Render(RENDER_FRAME_INTERVAL);
65     time += RENDER_FRAME_INTERVAL;
66   }
67
68   return time;
69 }
70
71 /**
72  * Creates a Ruler that snaps to a specified grid size.
73  * If that grid size is 0.0 then this ruler does not
74  * snap.
75  *
76  * @param[in] gridSize (optional) The grid size for the ruler,
77  * (Default = 0.0 i.e. no snapping)
78  * @return The ruler is returned.
79  */
80 RulerPtr CreateRuler(float gridSize = 0.0f)
81 {
82   if(gridSize <= Math::MACHINE_EPSILON_0)
83   {
84       return new DefaultRuler();
85   }
86   return new FixedRuler(gridSize);
87 }
88
89 // Callback probes.
90
91 static bool gOnScrollStartCalled;                       ///< Whether the OnScrollStart signal was invoked.
92 static bool gOnScrollUpdateCalled;                      ///< Whether the OnScrollUpdate signal was invoked.
93 static bool gOnScrollCompleteCalled;                    ///< Whether the OnScrollComplete signal was invoked.
94 static Vector3 gConstraintResult;                       ///< Result from constraint.
95
96 static ActorContainer gPages;                                ///< Keeps track of all the pages for applying effects.
97
98 static void ResetScrollCallbackResults()
99 {
100   gOnScrollStartCalled = false;
101   gOnScrollUpdateCalled = false;
102   gOnScrollCompleteCalled = false;
103 }
104
105 /**
106  * Invoked when scrolling starts.
107  *
108  * @param[in] position The current scroll position.
109  */
110 static void OnScrollStart( const Vector3& position )
111 {
112   gOnScrollStartCalled = true;
113 }
114
115 /**
116  * Invoked when scrolling updates (via dragging)
117  *
118  * @param[in] position The current scroll position.
119  */
120 static void OnScrollUpdate( const Vector3& position )
121 {
122   gOnScrollUpdateCalled = true;
123 }
124
125 /**
126  * Invoked when scrolling finishes
127  *
128  * @param[in] position The current scroll position.
129  */
130 static void OnScrollComplete( const Vector3& position )
131 {
132   gOnScrollCompleteCalled = true;
133 }
134
135
136 ScrollView SetupTestScrollView(int rows, int columns, Vector2 size)
137 {
138   ScrollView scrollView = ScrollView::New();
139   scrollView.SetSize(size);
140   scrollView.SetAnchorPoint(AnchorPoint::CENTER);
141   scrollView.SetParentOrigin(ParentOrigin::CENTER);
142   scrollView.ApplyConstraint( Constraint::New<Dali::Vector3>( Dali::Actor::SIZE, Dali::ParentSource( Dali::Actor::SIZE ), Dali::EqualToConstraint() ) );
143   // Disable Refresh signal (TET environment cannot use adaptor's Timer)
144   scrollView.SetWrapMode(false);
145   scrollView.SetRefreshInterval(0);
146   scrollView.ScrollStartedSignal().Connect( &OnScrollStart );
147   scrollView.ScrollUpdatedSignal().Connect( &OnScrollUpdate );
148   scrollView.ScrollCompletedSignal().Connect( &OnScrollComplete );
149   Stage::GetCurrent().Add( scrollView );
150   RulerPtr rulerX = CreateRuler(size.width);
151   RulerPtr rulerY = CreateRuler(size.height);
152   if(columns > 1)
153   {
154     rulerX->SetDomain(RulerDomain(0.0f, size.width * columns));
155   }
156   else
157   {
158     rulerX->Disable();
159   }
160   if(rows > 1)
161   {
162     rulerY->SetDomain(RulerDomain(0.0f, size.width * rows));
163   }
164   else
165   {
166     rulerY->Disable();
167   }
168
169   scrollView.SetRulerX( rulerX );
170   scrollView.SetRulerY( rulerY );
171   Stage::GetCurrent().Add( scrollView );
172
173   Actor container = Actor::New();
174   container.SetParentOrigin(ParentOrigin::CENTER);
175   container.SetAnchorPoint(AnchorPoint::CENTER);
176   container.SetSize( size );
177   scrollView.Add( container );
178   container.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
179
180   gPages.clear();
181   for(int row = 0;row<rows;row++)
182   {
183     for(int column = 0;column<columns;column++)
184     {
185       Actor page = Actor::New();
186       page.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
187       page.SetParentOrigin( ParentOrigin::CENTER );
188       page.SetAnchorPoint( AnchorPoint::CENTER );
189       page.SetPosition( column * size.x, row * size.y );
190       container.Add(page);
191
192       gPages.push_back(page);
193     }
194   }
195
196   ResetScrollCallbackResults();
197   return scrollView;
198 }
199
200 void CleanupTest()
201 {
202   gPages.clear();
203   ResetScrollCallbackResults();
204 }
205
206 Actor AddActorToPage(Actor page, float x, float y, float cols, float rows)
207 {
208   Stage stage = Stage::GetCurrent();
209   Vector2 stageSize = stage.GetSize();
210
211   const float margin = 10.0f;
212   const Vector2 actorSize((stageSize.x / cols) - margin, (stageSize.y / rows) - margin);
213
214   Actor actor = Actor::New();
215   actor.SetParentOrigin( ParentOrigin::CENTER );
216   actor.SetAnchorPoint( AnchorPoint::CENTER );
217
218   Vector3 position( margin * 0.5f + (actorSize.x + margin) * x - stageSize.width * 0.5f,
219                     margin * 0.5f + (actorSize.y + margin) * y - stageSize.height * 0.5f,
220                     0.0f);
221   Vector3 positionEnd( margin * 0.5f + (actorSize.x + margin) * (x + cols) - stageSize.width * 0.5f - margin,
222                        margin * 0.5f + (actorSize.y + margin) * (y + rows) - stageSize.height * 0.5f - margin,
223                        0.0f);
224   Vector3 size(positionEnd - position);
225   actor.SetPosition( position + size * 0.5f);
226   actor.SetSize( positionEnd - position );
227   page.Add(actor);
228   return actor;
229 }
230
231 } // unnamed namespace
232
233
234 int UtcDaliScrollViewPageCubeEffectSetup(void)
235 {
236   tet_infoline(" UtcDaliScrollViewPageCubeEffectSetup");
237
238   ScrollViewPageCubeEffect effect;
239
240   DALI_TEST_CHECK( !effect );
241
242   BaseHandle handle = ScrollViewPageCubeEffect::New();
243
244   DALI_TEST_CHECK( handle );
245
246   effect = ScrollViewPageCubeEffect::DownCast(handle);
247
248   DALI_TEST_CHECK( effect );
249   END_TEST;
250 }
251
252
253 int UtcDaliScrollViewPageCarouselEffectSetup(void)
254 {
255   tet_infoline(" UtcDaliScrollViewCarouselEffectSetup");
256
257   ScrollViewPageCarouselEffect effect;
258
259   DALI_TEST_CHECK( !effect );
260
261   BaseHandle handle = ScrollViewPageCarouselEffect::New();
262
263   DALI_TEST_CHECK( handle );
264
265   effect = ScrollViewPageCarouselEffect::DownCast(handle);
266
267   DALI_TEST_CHECK( effect );
268   END_TEST;
269 }
270
271 int UtcDaliScrollViewCarouselEffectSetup(void)
272 {
273   tet_infoline(" UtcDaliScrollViewCarouselEffectSetup");
274
275   ScrollViewCarouselEffect effect;
276
277   DALI_TEST_CHECK( !effect );
278
279   BaseHandle handle = ScrollViewCarouselEffect::New();
280
281   DALI_TEST_CHECK( handle );
282
283   effect = ScrollViewCarouselEffect::DownCast(handle);
284
285   DALI_TEST_CHECK( effect );
286   END_TEST;
287 }
288
289 int UtcDaliScrollViewDepthEffectSetup(void)
290 {
291   tet_infoline(" UtcDaliScrollViewDepthEffectSetup");
292
293   ScrollViewDepthEffect effect;
294
295   DALI_TEST_CHECK( !effect );
296
297   BaseHandle handle = ScrollViewDepthEffect::New();
298
299   DALI_TEST_CHECK( handle );
300
301   effect = ScrollViewDepthEffect::DownCast(handle);
302
303   DALI_TEST_CHECK( effect );
304   END_TEST;
305 }
306
307
308 int UtcDaliScrollViewPageCubeEffectTest(void)
309 {
310   ToolkitTestApplication application;
311   tet_infoline(" UtcDaliScrollViewPageCubeEffectTest");
312
313   Vector2 size = Stage::GetCurrent().GetSize();
314
315   ScrollView scrollView = SetupTestScrollView(1, 3, size);
316   Actor testPage = gPages[1];
317   Wait(application, 500);
318
319   ScrollViewPageCubeEffect effect = ScrollViewPageCubeEffect::New();
320   scrollView.ApplyEffect(effect);
321
322   for(ActorIter pageIter = gPages.begin(); pageIter != gPages.end(); ++pageIter)
323   {
324     Actor page = *pageIter;
325     page.RemoveConstraints();
326     page.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
327     effect.ApplyToPage(page, Vector2(Math::PI_2, 0.0f));
328   }
329   Wait(application);
330
331   scrollView.ScrollTo(1);
332   while(!gOnScrollCompleteCalled)
333   {
334     Wait(application);
335   }
336   // test that the first page has reached centre of screen
337   Vector3 pagePos = testPage.GetCurrentPosition();
338   DALI_TEST_EQUALS(pagePos, Vector3::ZERO, Math::MACHINE_EPSILON_0, TEST_LOCATION);
339   CleanupTest();
340   END_TEST;
341 }
342
343 int UtcDaliScrollViewPageCarouselEffectTest(void)
344 {
345   ToolkitTestApplication application;
346   tet_infoline(" UtcDaliScrollViewPageCarouselEffectTest");
347
348   Vector2 size = Stage::GetCurrent().GetSize();
349
350   ScrollView scrollView = SetupTestScrollView(1, 3, size);
351   Actor testPage = gPages[1];
352   Wait(application, 500);
353
354   ScrollViewPageCarouselEffect effect = ScrollViewPageCarouselEffect::New();
355   scrollView.ApplyEffect(effect);
356
357   for(ActorIter pageIter = gPages.begin(); pageIter != gPages.end(); ++pageIter)
358   {
359     Actor page = *pageIter;
360     page.RemoveConstraints();
361     page.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
362     effect.ApplyToPage(page);
363   }
364   Wait(application);
365
366   scrollView.ScrollTo(1, 0.5f, DirectionBiasNone);
367   while(!gOnScrollCompleteCalled)
368   {
369     Wait(application);
370   }
371   // test that the first page has reached centre of screen
372   Vector3 pagePos = testPage.GetCurrentPosition();
373   DALI_TEST_EQUALS(pagePos, Vector3::ZERO, Math::MACHINE_EPSILON_0, TEST_LOCATION);
374   CleanupTest();
375   END_TEST;
376 }
377
378 int UtcDaliScrollViewCarouselEffectTest(void)
379 {
380   ToolkitTestApplication application;
381   tet_infoline(" UtcDaliScrollViewCarouselEffectTest");
382
383   Vector2 size = Stage::GetCurrent().GetSize();
384
385   ScrollView scrollView = SetupTestScrollView(1, 3, size);
386   Actor testPage = gPages[1];
387   Wait(application, 500);
388
389   ScrollViewCarouselEffect effect = ScrollViewCarouselEffect::New();
390   scrollView.ApplyEffect(effect);
391
392   Actor actor = AddActorToPage(testPage, 0.5f, 0.5f, 3, 3);
393   Wait(application);
394   Vector3 actorPrePosition = actor.GetCurrentPosition();
395
396   effect.ApplyToActor( actor, Vector2(1.2f, 1.2f) );
397
398   scrollView.ScrollTo(Vector3(size.x, 0.0f, 0.0f), 0.5f, DirectionBiasNone, DirectionBiasNone);
399   while(!gOnScrollCompleteCalled)
400   {
401     Wait(application);
402   }
403   // test that the first page has reached centre of screen
404   Vector3 actorPostPosition = actor.GetCurrentPosition();
405   // just check the actor has moved
406   DALI_TEST_CHECK((actorPostPosition - actorPrePosition).Length() > Math::MACHINE_EPSILON_1);
407   CleanupTest();
408   END_TEST;
409 }
410
411 int UtcDaliScrollViewDepthEffectTest(void)
412 {
413   ToolkitTestApplication application;
414   tet_infoline(" UtcDaliScrollViewDepthEffectTest");
415
416   Vector2 size = Stage::GetCurrent().GetSize();
417
418   ScrollView scrollView = SetupTestScrollView(1, 3, size);
419   Actor testPage = gPages[1];
420   Wait(application, 500);
421
422   ScrollViewDepthEffect effect = ScrollViewDepthEffect::New();
423   scrollView.ApplyEffect(effect);
424
425   Actor actor = AddActorToPage(testPage, 0.5f, 0.5f, 3, 3);
426   Wait(application);
427   Vector3 actorPrePosition = actor.GetCurrentPosition();
428
429   const Vector2 positionExtent(0.5f, 2.5f);
430   const Vector2 offsetExtent(1.0f, 1.0f);
431   const float positionScale(1.5f);
432   const float scaleExtent(0.5f);
433
434   effect.ApplyToActor( actor, positionExtent, offsetExtent, positionScale, scaleExtent );
435
436   scrollView.ScrollTo(1);
437   while(!gOnScrollCompleteCalled)
438   {
439     Wait(application);
440   }
441   // test that the first page has reached centre of screen
442   Vector3 actorPostPosition = actor.GetCurrentPosition();
443   // just check the actor has moved
444   DALI_TEST_CHECK((actorPostPosition - actorPrePosition).Length() > Math::MACHINE_EPSILON_1);
445   CleanupTest();
446   END_TEST;
447 }