Merge branch 'devel/masteri (1.2.36+)' into tizen
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Constrainer.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
20 #include <stdlib.h>
21 #include <dali/public-api/dali-core.h>
22 #include <dali/devel-api/animation/path-constrainer.h>
23 #include <dali/devel-api/object/handle-devel.h>
24 #include <dali-test-suite-utils.h>
25
26 using namespace Dali;
27 using namespace Dali::Internal;
28
29 namespace
30 {
31
32 static void SetupPath( Dali::Path& path)
33 {
34   path.AddPoint(Vector3( 30.0,  80.0, 0.0));
35   path.AddPoint(Vector3( 70.0, 120.0, 0.0));
36   path.AddPoint(Vector3(100.0, 100.0, 0.0));
37
38   //Control points for first segment
39   path.AddControlPoint( Vector3( 39.0,  90.0, 0.0) );
40   path.AddControlPoint(Vector3( 56.0, 119.0, 0.0) );
41
42   //Control points for second segment
43   path.AddControlPoint(Vector3( 78.0, 120.0, 0.0) );
44   path.AddControlPoint(Vector3( 93.0, 104.0, 0.0) );
45 }
46
47 static void SetupPathConstrainer( Dali::PathConstrainer& PathConstrainer)
48 {
49   PathConstrainer.SetProperty( Dali::PathConstrainer::Property::FORWARD, Vector3(1.0f,0.0f,0.0f) );
50
51   Dali::Property::Array points;
52   points.Resize(3);
53   points[0] = Vector3( 30.0,  80.0, 0.0);
54   points[1] = Vector3( 70.0, 120.0, 0.0);
55   points[2] = Vector3(100.0, 100.0, 0.0);
56   PathConstrainer.SetProperty( Dali::PathConstrainer::Property::POINTS, points );
57
58   points.Resize(4);
59   points[0] = Vector3( 39.0,  90.0, 0.0);
60   points[1] = Vector3( 56.0, 119.0, 0.0);
61   points[2] = Vector3( 78.0, 120.0, 0.0);
62   points[3] = Vector3( 93.0, 104.0, 0.0);
63   PathConstrainer.SetProperty( Dali::PathConstrainer::Property::CONTROL_POINTS, points );
64 }
65
66 static void SetupLinearConstrainerUniformProgress( Dali::LinearConstrainer& linearConstrainer)
67 {
68   Dali::Property::Array points;
69   points.Resize(3);
70   points[0] = 0.0f;
71   points[1] = 1.0f;
72   points[2] = 0.0f;
73   linearConstrainer.SetProperty( Dali::LinearConstrainer::Property::VALUE, points );
74 }
75
76 static void SetupLinearConstrainerNonUniformProgress( Dali::LinearConstrainer& linearConstrainer)
77 {
78   Dali::Property::Array points;
79   points.Resize(3);
80   points[0] = 0.0f;
81   points[1] = 1.0f;
82   points[2] = 0.0f;
83   linearConstrainer.SetProperty( Dali::LinearConstrainer::Property::VALUE, points );
84
85   points[0] = 0.0f;
86   points[1] = 0.25f;
87   points[2] = 1.0f;
88   linearConstrainer.SetProperty( Dali::LinearConstrainer::Property::PROGRESS, points );
89 }
90
91 } // anonymous namespace
92
93 //PathConstrainer test cases
94 int UtcPathConstrainerApply(void)
95 {
96   TestApplication application;
97
98   Dali::Actor actor = Dali::Actor::New();
99
100   // Register a float property
101   Property::Index index = actor.RegisterProperty( "t", 0.0f );
102
103   Dali::Stage::GetCurrent().Add(actor);
104
105   //Create a Path
106   Dali::Path path = Dali::Path::New();
107   SetupPath(path);
108
109   //Create a PathConstrainer
110   Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
111   SetupPathConstrainer( pathConstrainer );
112
113   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
114   Vector2 range( 0.0f, 1.0f );
115   pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
116
117   //Create an animation to animate the custom property
118   float durationSeconds(1.0f);
119   Dali::Animation animation = Dali::Animation::New(durationSeconds);
120   animation.AnimateTo(Dali::Property(actor,index),1.0f);
121   animation.Play();
122
123   application.SendNotification();
124   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 20% progress */);
125
126   Vector3 position, tangent;
127   path.Sample(0.2f, position, tangent );
128   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
129
130   application.SendNotification();
131   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 40% progress */);
132   path.Sample(0.4f, position, tangent );
133   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
134
135   application.SendNotification();
136   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 60% progress */);
137   path.Sample(0.6f, position, tangent );
138   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
139
140   application.SendNotification();
141   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 80% progress */);
142   path.Sample(0.8f, position, tangent );
143   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
144
145   application.SendNotification();
146   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 100% progress */);
147   path.Sample(1.0f, position, tangent );
148   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
149
150   application.SendNotification();
151   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* beyond the animation duration*/);
152   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
153
154   END_TEST;
155 }
156
157 int UtcPathConstrainerApplyRange(void)
158 {
159   TestApplication application;
160
161   Dali::Actor actor = Dali::Actor::New();
162
163   // Register a float property
164   Property::Index index = actor.RegisterProperty( "t", 0.0f );
165   Dali::Stage::GetCurrent().Add(actor);
166
167   //Create a Path
168   Dali::Path path = Dali::Path::New();
169   SetupPath(path);
170
171   //Create a PathConstrainer
172   Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
173   SetupPathConstrainer( pathConstrainer );
174
175   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
176   Vector2 range( 100.0f, 300.0f );
177   pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
178
179
180   //Create an animation to animate the custom property
181   float durationSeconds(1.0f);
182   Dali::Animation animation = Dali::Animation::New(durationSeconds);
183   animation.AnimateTo(Dali::Property(actor,index),400.0f);
184   animation.Play();
185
186   application.SendNotification();
187   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
188
189
190   Vector3 position, tangent;
191   float tValue;
192   actor.GetProperty(index).Get(tValue);
193   float currentCursor =  ( tValue - range.x ) / (range.y-range.x);
194   path.Sample(currentCursor, position, tangent );
195   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
196
197   application.SendNotification();
198   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
199   actor.GetProperty(index).Get(tValue);
200   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
201   path.Sample(currentCursor, position, tangent );
202   path.Sample(0.5, position, tangent );
203   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
204
205   application.SendNotification();
206   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
207   DevelHandle::GetCurrentProperty( actor, index ).Get( tValue );
208   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
209   path.Sample(currentCursor, position, tangent );
210   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
211
212   application.SendNotification();
213   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
214   DevelHandle::GetCurrentProperty( actor, index ).Get( tValue );
215   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
216   path.Sample(currentCursor, position, tangent );
217   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
218
219   application.SendNotification();
220   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
221   DevelHandle::GetCurrentProperty( actor, index ).Get( tValue );
222   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
223   path.Sample(currentCursor, position, tangent );
224   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
225
226   END_TEST;
227 }
228
229 int UtcPathConstrainerDestroy(void)
230 {
231   TestApplication application;
232
233   Dali::Actor actor = Dali::Actor::New();
234
235   // Register a float property
236   Property::Index index = actor.RegisterProperty( "t", 0.0f );
237   Dali::Stage::GetCurrent().Add(actor);
238
239   {
240     //Create a Path
241     Dali::Path path = Dali::Path::New();
242     SetupPath(path);
243
244     //Create a PathConstrainer
245     Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
246     SetupPathConstrainer( pathConstrainer );
247
248     //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
249     Vector2 range( 0.0f, 1.0f );
250     pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
251
252     //Test that the constraint is correctly applied
253     actor.SetProperty(index,0.5f);
254     application.SendNotification();
255     application.Render(static_cast<unsigned int>(1.0f));
256
257     Vector3 position, tangent;
258     path.Sample(0.5f, position, tangent );
259     DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
260
261   }
262
263   //PathConstrainer has been destroyed. Constraint in the actor should have been removed
264   actor.SetProperty(index,0.75f);
265   application.SendNotification();
266   application.Render(static_cast<unsigned int>(1.0f));
267
268   DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION );
269
270   END_TEST;
271 }
272
273 int UtcPathConstrainerRemove(void)
274 {
275   TestApplication application;
276
277   Dali::Actor actor = Dali::Actor::New();
278
279   // Register a float property
280   Property::Index index = actor.RegisterProperty( "t", 0.0f );
281   Dali::Stage::GetCurrent().Add(actor);
282
283   //Create a Path
284   Dali::Path path = Dali::Path::New();
285   SetupPath(path);
286
287   //Create a PathConstrainer
288   Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
289   SetupPathConstrainer( pathConstrainer );
290
291   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
292   Vector2 range( 0.0f, 1.0f );
293   pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
294
295   //Test that the constraint is correctly applied
296   actor.SetProperty(index,0.5f);
297   application.SendNotification();
298   application.Render(static_cast<unsigned int>(1.0f));
299
300   Vector3 position, tangent;
301   path.Sample(0.5f, position, tangent );
302   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
303
304   //Remove constraint
305   pathConstrainer.Remove( actor );
306   actor.SetProperty(index,0.75f);
307   application.SendNotification();
308   application.Render(static_cast<unsigned int>(1.0f));
309
310   DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION );
311
312   END_TEST;
313 }
314
315 //LinearConstrainer test cases
316 int UtcLinearConstrainerDownCast(void)
317 {
318   TestApplication application;
319   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
320
321   BaseHandle handle( linearConstrainer );
322   Dali::LinearConstrainer linearConstrainer2 = Dali::LinearConstrainer::DownCast( handle );
323   DALI_TEST_EQUALS( (bool)linearConstrainer2, true, TEST_LOCATION );
324
325   BaseHandle handle2;
326   Dali:: LinearConstrainer linearConstrainer3 = Dali::LinearConstrainer::DownCast( handle2 );
327   DALI_TEST_EQUALS( (bool)linearConstrainer3, false, TEST_LOCATION );
328
329   END_TEST;
330 }
331
332 int UtcLinearConstrainerCopyConstructor(void)
333 {
334   TestApplication application;
335   Dali::LinearConstrainer linearConstrainer;
336   DALI_TEST_EQUALS( (bool)linearConstrainer, false, TEST_LOCATION );
337
338   linearConstrainer = Dali::LinearConstrainer::New();
339   DALI_TEST_EQUALS( (bool)linearConstrainer, true, TEST_LOCATION );
340
341   // call the copy constructor
342   Dali::LinearConstrainer linearConstrainer2( linearConstrainer );
343   DALI_TEST_EQUALS( (bool)linearConstrainer2, true, TEST_LOCATION );
344
345   END_TEST;
346 }
347
348 int UtcLinearConstrainerApply(void)
349 {
350   TestApplication application;
351
352   Dali::Actor actor = Dali::Actor::New();
353
354   // Register a float property
355   Property::Index index = actor.RegisterProperty( "t", 0.0f );
356
357   Dali::Stage::GetCurrent().Add(actor);
358
359
360   //Create a LinearConstrainer without specifying progress for values
361   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
362   SetupLinearConstrainerUniformProgress( linearConstrainer );
363
364   //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
365   Vector2 range( 0.0f, 1.0f );
366   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
367
368   //Create an animation to animate the custom property
369   float durationSeconds(1.0f);
370   Dali::Animation animation = Dali::Animation::New(durationSeconds);
371   animation.AnimateTo(Dali::Property(actor,index),1.0f);
372   animation.Play();
373
374   application.SendNotification();
375   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
376
377   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
378
379   application.SendNotification();
380   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
381   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
382
383   application.SendNotification();
384   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
385   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
386
387   application.SendNotification();
388   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
389   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
390
391   application.SendNotification();
392   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
393   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
394
395   //Setup a LinearConstrainer specifying the progress for each value
396   linearConstrainer.Remove(actor);
397   SetupLinearConstrainerNonUniformProgress( linearConstrainer );
398   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
399
400   actor.SetProperty(index,0.0f);
401   animation.Play();
402   application.SendNotification();
403   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
404
405   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
406
407   application.SendNotification();
408   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
409   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 2.0f/3.0f, Math::MACHINE_EPSILON_1, TEST_LOCATION );
410
411   application.SendNotification();
412   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
413   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f/3.0f, Math::MACHINE_EPSILON_1, TEST_LOCATION );
414
415   application.SendNotification();
416   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
417   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
418
419   application.SendNotification();
420   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
421   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
422
423   END_TEST;
424 }
425
426 int UtcLinearConstrainerApplyRange(void)
427 {
428   TestApplication application;
429
430   Dali::Actor actor = Dali::Actor::New();
431
432   // Register a float property
433   Property::Index index = actor.RegisterProperty( "t", 100.0f );
434   Dali::Stage::GetCurrent().Add(actor);
435
436   //Create a LinearConstrainer
437   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
438   SetupLinearConstrainerUniformProgress( linearConstrainer );
439
440   //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
441   Vector2 range( 100.0f, 300.0f );
442   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
443
444
445   //Create an animation to animate the custom property
446   float durationSeconds(1.0f);
447   Dali::Animation animation = Dali::Animation::New(durationSeconds);
448   animation.AnimateTo(Dali::Property(actor,index),300.0f);
449   animation.Play();
450
451   application.SendNotification();
452   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
453
454   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
455
456   application.SendNotification();
457   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
458   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
459
460   application.SendNotification();
461   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
462   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
463
464   application.SendNotification();
465   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
466   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
467
468   application.SendNotification();
469   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
470   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
471
472   END_TEST;
473 }
474
475 int UtcLinearConstrainerDestroy(void)
476 {
477   TestApplication application;
478
479   Dali::Actor actor = Dali::Actor::New();
480
481   // Register a float property
482   Property::Index index = actor.RegisterProperty( "t", 0.0f );
483   Dali::Stage::GetCurrent().Add(actor);
484
485   {
486     //Create a LinearConstrainer
487     Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
488     SetupLinearConstrainerUniformProgress( linearConstrainer );
489
490     //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
491     Vector2 range( 0.0f, 1.0f );
492     linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
493
494     //Test that the constraint is correctly applied
495     actor.SetProperty(index,0.5f);
496     application.SendNotification();
497     application.Render(static_cast<unsigned int>(1.0f));
498
499     DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
500
501   }
502
503   //LinearConstrainer has been destroyed. Constraint in the actor should have been removed
504   actor.SetProperty(index,0.75f);
505   application.SendNotification();
506   application.Render(static_cast<unsigned int>(1.0f));
507
508   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
509
510   END_TEST;
511 }
512
513 int UtcLinearConstrainerRemove(void)
514 {
515   TestApplication application;
516
517   Dali::Actor actor = Dali::Actor::New();
518
519   // Register a float property
520   Property::Index index = actor.RegisterProperty( "t", 0.0f );
521   Dali::Stage::GetCurrent().Add(actor);
522
523   //Create a LinearConstrainer
524   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
525   SetupLinearConstrainerUniformProgress( linearConstrainer );
526
527   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
528   Vector2 range( 0.0f, 1.0f );
529   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
530
531   //Test that the constraint is correctly applied
532   actor.SetProperty(index,0.5f);
533   application.SendNotification();
534   application.Render(static_cast<unsigned int>(1.0f));
535
536   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
537
538   //Remove constraint
539   linearConstrainer.Remove( actor );
540   actor.SetProperty(index,0.75f);
541   application.SendNotification();
542   application.Render(static_cast<unsigned int>(1.0f));
543
544   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
545
546   END_TEST;
547 }