Merge "Add Visual descriptions to generate doxygen page" into devel/master
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / utc-Dali-ScrollViewEffect.cpp
1 /*
2  * Copyright (c) 2017 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 #include <dali/integration-api/events/pan-gesture-event.h>
29
30 using namespace Dali;
31 using namespace Toolkit;
32
33 void utc_dali_toolkit_scroll_view_effect_startup(void)
34 {
35   test_return_value = TET_UNDEF;
36 }
37
38 void utc_dali_toolkit_scroll_view_effect_cleanup(void)
39 {
40   test_return_value = TET_PASS;
41 }
42
43 namespace
44 {
45
46 const int RENDER_FRAME_INTERVAL = 16;                           ///< Duration of each frame in ms. (at approx 60FPS)
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 std::vector< Actor > gPages;                                ///< Keeps track of all the pages for applying effects.
97 typedef std::vector< Actor >::iterator ActorIter;
98
99 static void ResetScrollCallbackResults()
100 {
101   gOnScrollStartCalled = false;
102   gOnScrollUpdateCalled = false;
103   gOnScrollCompleteCalled = false;
104 }
105
106 /**
107  * Invoked when scrolling starts.
108  *
109  * @param[in] position The current scroll position.
110  */
111 static void OnScrollStart( const Vector2& position )
112 {
113   gOnScrollStartCalled = true;
114 }
115
116 /**
117  * Invoked when scrolling updates (via dragging)
118  *
119  * @param[in] position The current scroll position.
120  */
121 static void OnScrollUpdate( const Vector2& position )
122 {
123   gOnScrollUpdateCalled = true;
124 }
125
126 /**
127  * Invoked when scrolling finishes
128  *
129  * @param[in] position The current scroll position.
130  */
131 static void OnScrollComplete( const Vector2& position )
132 {
133   gOnScrollCompleteCalled = true;
134 }
135
136 ScrollView SetupTestScrollView(int rows, int columns, Vector2 size)
137 {
138   Constraint constraint;
139
140   ScrollView scrollView = ScrollView::New();
141   scrollView.SetSize(size);
142   scrollView.SetAnchorPoint(AnchorPoint::CENTER);
143   scrollView.SetParentOrigin(ParentOrigin::CENTER);
144
145   constraint = Constraint::New<Dali::Vector3>( scrollView, Dali::Actor::Property::SIZE, Dali::EqualToConstraint() );
146   constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
147   constraint.Apply();
148
149   scrollView.SetWrapMode(false);
150   scrollView.ScrollStartedSignal().Connect( &OnScrollStart );
151   scrollView.ScrollUpdatedSignal().Connect( &OnScrollUpdate );
152   scrollView.ScrollCompletedSignal().Connect( &OnScrollComplete );
153   Stage::GetCurrent().Add( scrollView );
154   RulerPtr rulerX = CreateRuler(size.width);
155   RulerPtr rulerY = CreateRuler(size.height);
156   if(columns > 1)
157   {
158     rulerX->SetDomain(RulerDomain(0.0f, size.width * columns));
159   }
160   else
161   {
162     rulerX->Disable();
163   }
164   if(rows > 1)
165   {
166     rulerY->SetDomain(RulerDomain(0.0f, size.width * rows));
167   }
168   else
169   {
170     rulerY->Disable();
171   }
172
173   scrollView.SetRulerX( rulerX );
174   scrollView.SetRulerY( rulerY );
175   Stage::GetCurrent().Add( scrollView );
176
177   Actor container = Actor::New();
178   container.SetParentOrigin(ParentOrigin::CENTER);
179   container.SetAnchorPoint(AnchorPoint::CENTER);
180   container.SetSize( size );
181   scrollView.Add( container );
182
183   constraint = Constraint::New<Vector3>( container, Actor::Property::SIZE, EqualToConstraint() );
184   constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
185   constraint.Apply();
186
187   gPages.clear();
188   for(int row = 0;row<rows;row++)
189   {
190     for(int column = 0;column<columns;column++)
191     {
192       Actor page = Actor::New();
193
194       constraint = Constraint::New<Vector3>( page, Actor::Property::SIZE, EqualToConstraint() );
195       constraint.AddSource( Dali::ParentSource( Dali::Actor::Property::SIZE ) );
196       constraint.Apply();
197       page.SetParentOrigin( ParentOrigin::CENTER );
198       page.SetAnchorPoint( AnchorPoint::CENTER );
199       page.SetPosition( column * size.x, row * size.y );
200       container.Add(page);
201
202       gPages.push_back(page);
203     }
204   }
205
206   ResetScrollCallbackResults();
207   return scrollView;
208 }
209
210 void CleanupTest()
211 {
212   gPages.clear();
213   ResetScrollCallbackResults();
214 }
215
216 } // unnamed namespace
217
218 int UtcDaliScrollViewPagePathEffectSetup(void)
219 {
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 = Stage::GetCurrent().GetSize();
242
243   ScrollView scrollView = SetupTestScrollView(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.GetCurrentPosition();
293   DALI_TEST_EQUALS(pagePos, Vector3::ZERO, Math::MACHINE_EPSILON_0, TEST_LOCATION);
294
295   CleanupTest();
296   END_TEST;
297 }