[dali_2.0.15] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / utc-Dali-ScrollViewEffect.cpp
1 /*
2  * Copyright (c) 2020 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 #include <stdlib.h>
20
21 // Need to override adaptor classes for toolkit test harness, so include
22 // test harness headers before dali headers.
23 #include <dali-toolkit-test-suite-utils.h>
24
25 #include <dali.h>
26 #include <dali-toolkit/dali-toolkit.h>
27 #include <dali/integration-api/events/touch-event-integ.h>
28
29 using namespace Dali;
30 using namespace Toolkit;
31
32 void utc_dali_toolkit_scroll_view_effect_startup(void)
33 {
34   test_return_value = TET_UNDEF;
35 }
36
37 void utc_dali_toolkit_scroll_view_effect_cleanup(void)
38 {
39   test_return_value = TET_PASS;
40 }
41
42 namespace
43 {
44
45 const int RENDER_FRAME_INTERVAL = 16;                           ///< Duration of each frame in ms. (at approx 60FPS)
46
47 /*
48  * Simulate time passed by.
49  *
50  * @note this will always process at least 1 frame (1/60 sec)
51  *
52  * @param application Test application instance
53  * @param duration Time to pass in milliseconds.
54  * @return The actual time passed in milliseconds
55  */
56 int Wait(ToolkitTestApplication& application, int duration = 0)
57 {
58   int time = 0;
59
60   for(int i = 0; i <= ( duration / RENDER_FRAME_INTERVAL); i++)
61   {
62     application.SendNotification();
63     application.Render(RENDER_FRAME_INTERVAL);
64     time += RENDER_FRAME_INTERVAL;
65   }
66
67   return time;
68 }
69
70 /**
71  * Creates a Ruler that snaps to a specified grid size.
72  * If that grid size is 0.0 then this ruler does not
73  * snap.
74  *
75  * @param[in] gridSize (optional) The grid size for the ruler,
76  * (Default = 0.0 i.e. no snapping)
77  * @return The ruler is returned.
78  */
79 RulerPtr CreateRuler(float gridSize = 0.0f)
80 {
81   if(gridSize <= Math::MACHINE_EPSILON_0)
82   {
83       return new DefaultRuler();
84   }
85   return new FixedRuler(gridSize);
86 }
87
88 // Callback probes.
89
90 static bool gOnScrollStartCalled;                       ///< Whether the OnScrollStart signal was invoked.
91 static bool gOnScrollUpdateCalled;                      ///< Whether the OnScrollUpdate signal was invoked.
92 static bool gOnScrollCompleteCalled;                    ///< Whether the OnScrollComplete signal was invoked.
93 static Vector3 gConstraintResult;                       ///< Result from constraint.
94
95 static std::vector< Actor > gPages;                                ///< Keeps track of all the pages for applying effects.
96 typedef std::vector< Actor >::iterator ActorIter;
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 Vector2& 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 Vector2& 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 Vector2& position )
131 {
132   gOnScrollCompleteCalled = true;
133 }
134
135 ScrollView SetupTestScrollView(Integration::Scene scene, int rows, int columns, Vector2 size)
136 {
137   Constraint constraint;
138
139   ScrollView scrollView = ScrollView::New();
140   scrollView.SetProperty( Actor::Property::SIZE, size);
141   scrollView.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::CENTER);
142   scrollView.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
143
144   constraint = Constraint::New<Dali::Vector3>( scrollView, Dali::Actor::Property::SIZE, Dali::EqualToConstraint() );
145   constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
146   constraint.Apply();
147
148   scrollView.SetWrapMode(false);
149   scrollView.ScrollStartedSignal().Connect( &OnScrollStart );
150   scrollView.ScrollUpdatedSignal().Connect( &OnScrollUpdate );
151   scrollView.ScrollCompletedSignal().Connect( &OnScrollComplete );
152   scene.Add( scrollView );
153   RulerPtr rulerX = CreateRuler(size.width);
154   RulerPtr rulerY = CreateRuler(size.height);
155   if(columns > 1)
156   {
157     rulerX->SetDomain(RulerDomain(0.0f, size.width * columns));
158   }
159   else
160   {
161     rulerX->Disable();
162   }
163   if(rows > 1)
164   {
165     rulerY->SetDomain(RulerDomain(0.0f, size.width * rows));
166   }
167   else
168   {
169     rulerY->Disable();
170   }
171
172   scrollView.SetRulerX( rulerX );
173   scrollView.SetRulerY( rulerY );
174   scene.Add( scrollView );
175
176   Actor container = Actor::New();
177   container.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
178   container.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::CENTER);
179   container.SetProperty( Actor::Property::SIZE, size );
180   scrollView.Add( container );
181
182   constraint = Constraint::New<Vector3>( container, Actor::Property::SIZE, EqualToConstraint() );
183   constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
184   constraint.Apply();
185
186   gPages.clear();
187   for(int row = 0;row<rows;row++)
188   {
189     for(int column = 0;column<columns;column++)
190     {
191       Actor page = Actor::New();
192
193       constraint = Constraint::New<Vector3>( page, Actor::Property::SIZE, EqualToConstraint() );
194       constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
195       constraint.Apply();
196       page.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
197       page.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
198       page.SetProperty( Actor::Property::POSITION, Vector2( column * size.x, row * size.y ));
199       container.Add(page);
200
201       gPages.push_back(page);
202     }
203   }
204
205   ResetScrollCallbackResults();
206   return scrollView;
207 }
208
209 void CleanupTest()
210 {
211   gPages.clear();
212   ResetScrollCallbackResults();
213 }
214
215 } // unnamed namespace
216
217 int UtcDaliScrollViewPagePathEffectSetup(void)
218 {
219   ToolkitTestApplication application;
220   tet_infoline(" UtcDaliScrollViewPagePathEffectSetup");
221
222   ScrollViewPagePathEffect effect;
223
224   DALI_TEST_CHECK( !effect );
225
226   BaseHandle handle = ScrollViewPagePathEffect::New(Dali::Path::New(), Vector3::ZERO,Toolkit::ScrollView::Property::SCROLL_FINAL_X, Vector3::ZERO,0);
227
228   DALI_TEST_CHECK( handle );
229
230   effect = ScrollViewPagePathEffect::DownCast(handle);
231
232   DALI_TEST_CHECK( effect );
233   END_TEST;
234 }
235
236 int UtcDaliScrollViewPagePathEffectTest(void)
237 {
238   ToolkitTestApplication application;
239   tet_infoline(" UtcDaliScrollViewPagePathEffectTest");
240
241   Vector2 size = application.GetScene().GetSize();
242
243   ScrollView scrollView = SetupTestScrollView(application.GetScene(), 1, 3, size);
244   Actor testPage = gPages[2];
245   Wait(application, 500);
246
247   //Create path
248   float xHalfSize( size.x * 0.5f);
249
250   Dali::Path path = Dali::Path::New();
251   Dali::Property::Array points;
252   points.Resize(3);
253   points[0] = Vector3( xHalfSize, 0.0f,  -xHalfSize);
254   points[1] = Vector3( 0.0f, 0.0f, 0.0f );
255   points[2] = Vector3( -xHalfSize, 0.0f,  -xHalfSize);
256   path.SetProperty( Path::Property::POINTS, points );
257
258   Dali::Property::Array controlPoints;
259   controlPoints.Resize(4);
260   controlPoints[0] = Vector3( xHalfSize, 0.0f, 0.0f );
261   controlPoints[1] = Vector3( xHalfSize, 0.0f, 0.0f );
262   controlPoints[2] = Vector3(-xHalfSize, 0.0f, 0.0f );
263   controlPoints[3] = Vector3(-xHalfSize, 0.0f, 0.0f );
264   path.SetProperty( Path::Property::CONTROL_POINTS, controlPoints );
265
266   ScrollViewPagePathEffect effect = ScrollViewPagePathEffect::New(path,
267                                                                   Vector3::ZERO,
268                                                                   Toolkit::ScrollView::Property::SCROLL_FINAL_X,
269                                                                   Vector3(size.x,size.y,0.0f),
270                                                                   3);
271   scrollView.ApplyEffect(effect);
272
273   unsigned int pageCounter(0);
274   for(ActorIter pageIter = gPages.begin(); pageIter != gPages.end(); ++pageIter)
275   {
276     Actor page = *pageIter;
277     page.RemoveConstraints();
278     Constraint constraint = Constraint::New<Vector3>( page, Actor::Property::SIZE, EqualToConstraint() );
279     constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
280     constraint.Apply();
281     effect.ApplyToPage(page, pageCounter++);
282   }
283   Wait(application);
284
285   scrollView.ScrollTo(1);
286   while(!gOnScrollCompleteCalled)
287   {
288     Wait(application);
289   }
290
291   // test that the test page has reached centre of screen
292   Vector3 pagePos = testPage.GetCurrentProperty< Vector3 >( Actor::Property::POSITION );
293   DALI_TEST_EQUALS(pagePos, Vector3::ZERO, Math::MACHINE_EPSILON_0, TEST_LOCATION);
294
295   CleanupTest();
296   END_TEST;
297 }