Ensure cached values of properties animated using AnimateTo are updated
[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   DevelHandle::GetCurrentProperty( actor, 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   DevelHandle::GetCurrentProperty( actor, 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   // Ensure GetProperty also returns the final result
227   actor.GetProperty( index ).Get( tValue );
228   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
229   path.Sample(currentCursor, position, tangent );
230   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
231
232   END_TEST;
233 }
234
235 int UtcPathConstrainerDestroy(void)
236 {
237   TestApplication application;
238
239   Dali::Actor actor = Dali::Actor::New();
240
241   // Register a float property
242   Property::Index index = actor.RegisterProperty( "t", 0.0f );
243   Dali::Stage::GetCurrent().Add(actor);
244
245   {
246     //Create a Path
247     Dali::Path path = Dali::Path::New();
248     SetupPath(path);
249
250     //Create a PathConstrainer
251     Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
252     SetupPathConstrainer( pathConstrainer );
253
254     //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
255     Vector2 range( 0.0f, 1.0f );
256     pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
257
258     //Test that the constraint is correctly applied
259     actor.SetProperty(index,0.5f);
260     application.SendNotification();
261     application.Render(static_cast<unsigned int>(1.0f));
262
263     Vector3 position, tangent;
264     path.Sample(0.5f, position, tangent );
265     DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
266
267   }
268
269   //PathConstrainer has been destroyed. Constraint in the actor should have been removed
270   actor.SetProperty(index,0.75f);
271   application.SendNotification();
272   application.Render(static_cast<unsigned int>(1.0f));
273
274   DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION );
275
276   END_TEST;
277 }
278
279 int UtcPathConstrainerRemove(void)
280 {
281   TestApplication application;
282
283   Dali::Actor actor = Dali::Actor::New();
284
285   // Register a float property
286   Property::Index index = actor.RegisterProperty( "t", 0.0f );
287   Dali::Stage::GetCurrent().Add(actor);
288
289   //Create a Path
290   Dali::Path path = Dali::Path::New();
291   SetupPath(path);
292
293   //Create a PathConstrainer
294   Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
295   SetupPathConstrainer( pathConstrainer );
296
297   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
298   Vector2 range( 0.0f, 1.0f );
299   pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
300
301   //Test that the constraint is correctly applied
302   actor.SetProperty(index,0.5f);
303   application.SendNotification();
304   application.Render(static_cast<unsigned int>(1.0f));
305
306   Vector3 position, tangent;
307   path.Sample(0.5f, position, tangent );
308   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
309
310   //Remove constraint
311   pathConstrainer.Remove( actor );
312   actor.SetProperty(index,0.75f);
313   application.SendNotification();
314   application.Render(static_cast<unsigned int>(1.0f));
315
316   DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION );
317
318   END_TEST;
319 }
320
321 int UtcPathConstrainerProperties(void)
322 {
323   TestApplication application;
324   Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
325
326   pathConstrainer.SetProperty( Dali::PathConstrainer::Property::FORWARD, Vector3( 1.0f,0.0f,0.0f ) );
327   DALI_TEST_EQUALS( pathConstrainer.GetProperty< Vector3 >( Dali::PathConstrainer::Property::FORWARD ), Vector3( 1.0f, 0.0f, 0.0f ), TEST_LOCATION );
328   DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( pathConstrainer, Dali::PathConstrainer::Property::FORWARD ), Vector3( 1.0f, 0.0f, 0.0f ), TEST_LOCATION );
329
330   Dali::Property::Array points;
331   points.Resize(3);
332   points[0] = Vector3( 30.0,  80.0, 0.0);
333   points[1] = Vector3( 70.0, 120.0, 0.0);
334   points[2] = Vector3(100.0, 100.0, 0.0);
335   pathConstrainer.SetProperty( Dali::PathConstrainer::Property::POINTS, points );
336
337   {
338     Property::Value value = pathConstrainer.GetProperty( Dali::PathConstrainer::Property::POINTS );
339     Property::Array* array = value.GetArray();
340     DALI_TEST_CHECK( array );
341
342     const unsigned int noOfPoints = points.Size();
343     for( unsigned int i = 0; i < noOfPoints; ++i )
344     {
345       DALI_TEST_EQUALS( ( *array )[i].Get< Vector3 >(), points[i].Get< Vector3 >(), TEST_LOCATION );
346     }
347   }
348
349   {
350     Property::Value value = DevelHandle::GetCurrentProperty( pathConstrainer, Dali::PathConstrainer::Property::POINTS );
351     Property::Array* array = value.GetArray();
352     DALI_TEST_CHECK( array );
353
354     const unsigned int noOfPoints = points.Size();
355     for( unsigned int i = 0; i < noOfPoints; ++i )
356     {
357       DALI_TEST_EQUALS( ( *array )[i].Get< Vector3 >(), points[i].Get< Vector3 >(), TEST_LOCATION );
358     }
359   }
360
361   points.Resize(4);
362   points[0] = Vector3( 39.0,  90.0, 0.0);
363   points[1] = Vector3( 56.0, 119.0, 0.0);
364   points[2] = Vector3( 78.0, 120.0, 0.0);
365   points[3] = Vector3( 93.0, 104.0, 0.0);
366   pathConstrainer.SetProperty( Dali::PathConstrainer::Property::CONTROL_POINTS, points );
367
368   {
369     Property::Value value = pathConstrainer.GetProperty( Dali::PathConstrainer::Property::CONTROL_POINTS );
370     Property::Array* array = value.GetArray();
371     DALI_TEST_CHECK( array );
372
373     const unsigned int noOfPoints = points.Size();
374     for( unsigned int i = 0; i < noOfPoints; ++i )
375     {
376       DALI_TEST_EQUALS( ( *array )[i].Get< Vector3 >(), points[i].Get< Vector3 >(), TEST_LOCATION );
377     }
378   }
379
380   {
381     Property::Value value = DevelHandle::GetCurrentProperty( pathConstrainer, Dali::PathConstrainer::Property::CONTROL_POINTS );
382     Property::Array* array = value.GetArray();
383     DALI_TEST_CHECK( array );
384
385     const unsigned int noOfPoints = points.Size();
386     for( unsigned int i = 0; i < noOfPoints; ++i )
387     {
388       DALI_TEST_EQUALS( ( *array )[i].Get< Vector3 >(), points[i].Get< Vector3 >(), TEST_LOCATION );
389     }
390   }
391
392   END_TEST;
393 }
394
395 //LinearConstrainer test cases
396 int UtcLinearConstrainerDownCast(void)
397 {
398   TestApplication application;
399   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
400
401   BaseHandle handle( linearConstrainer );
402   Dali::LinearConstrainer linearConstrainer2 = Dali::LinearConstrainer::DownCast( handle );
403   DALI_TEST_EQUALS( (bool)linearConstrainer2, true, TEST_LOCATION );
404
405   BaseHandle handle2;
406   Dali:: LinearConstrainer linearConstrainer3 = Dali::LinearConstrainer::DownCast( handle2 );
407   DALI_TEST_EQUALS( (bool)linearConstrainer3, false, TEST_LOCATION );
408
409   END_TEST;
410 }
411
412 int UtcLinearConstrainerCopyConstructor(void)
413 {
414   TestApplication application;
415   Dali::LinearConstrainer linearConstrainer;
416   DALI_TEST_EQUALS( (bool)linearConstrainer, false, TEST_LOCATION );
417
418   linearConstrainer = Dali::LinearConstrainer::New();
419   DALI_TEST_EQUALS( (bool)linearConstrainer, true, TEST_LOCATION );
420
421   // call the copy constructor
422   Dali::LinearConstrainer linearConstrainer2( linearConstrainer );
423   DALI_TEST_EQUALS( (bool)linearConstrainer2, true, TEST_LOCATION );
424
425   END_TEST;
426 }
427
428 int UtcLinearConstrainerApply(void)
429 {
430   TestApplication application;
431
432   Dali::Actor actor = Dali::Actor::New();
433
434   // Register a float property
435   Property::Index index = actor.RegisterProperty( "t", 0.0f );
436
437   Dali::Stage::GetCurrent().Add(actor);
438
439
440   //Create a LinearConstrainer without specifying progress for values
441   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
442   SetupLinearConstrainerUniformProgress( linearConstrainer );
443
444   //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
445   Vector2 range( 0.0f, 1.0f );
446   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
447
448   //Create an animation to animate the custom property
449   float durationSeconds(1.0f);
450   Dali::Animation animation = Dali::Animation::New(durationSeconds);
451   animation.AnimateTo(Dali::Property(actor,index),1.0f);
452   animation.Play();
453
454   application.SendNotification();
455   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
456
457   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
458
459   application.SendNotification();
460   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
461   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
462
463   application.SendNotification();
464   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
465   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
466
467   application.SendNotification();
468   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
469   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
470
471   application.SendNotification();
472   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
473   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
474
475   //Setup a LinearConstrainer specifying the progress for each value
476   linearConstrainer.Remove(actor);
477   SetupLinearConstrainerNonUniformProgress( linearConstrainer );
478   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
479
480   actor.SetProperty(index,0.0f);
481   animation.Play();
482   application.SendNotification();
483   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
484
485   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
486
487   application.SendNotification();
488   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
489   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 2.0f/3.0f, Math::MACHINE_EPSILON_1, TEST_LOCATION );
490
491   application.SendNotification();
492   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
493   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f/3.0f, Math::MACHINE_EPSILON_1, TEST_LOCATION );
494
495   application.SendNotification();
496   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
497   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
498
499   application.SendNotification();
500   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
501   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
502
503   END_TEST;
504 }
505
506 int UtcLinearConstrainerApplyRange(void)
507 {
508   TestApplication application;
509
510   Dali::Actor actor = Dali::Actor::New();
511
512   // Register a float property
513   Property::Index index = actor.RegisterProperty( "t", 100.0f );
514   Dali::Stage::GetCurrent().Add(actor);
515
516   //Create a LinearConstrainer
517   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
518   SetupLinearConstrainerUniformProgress( linearConstrainer );
519
520   //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
521   Vector2 range( 100.0f, 300.0f );
522   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
523
524
525   //Create an animation to animate the custom property
526   float durationSeconds(1.0f);
527   Dali::Animation animation = Dali::Animation::New(durationSeconds);
528   animation.AnimateTo(Dali::Property(actor,index),300.0f);
529   animation.Play();
530
531   application.SendNotification();
532   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
533
534   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
535
536   application.SendNotification();
537   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
538   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
539
540   application.SendNotification();
541   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
542   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
543
544   application.SendNotification();
545   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
546   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
547
548   application.SendNotification();
549   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
550   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
551
552   END_TEST;
553 }
554
555 int UtcLinearConstrainerDestroy(void)
556 {
557   TestApplication application;
558
559   Dali::Actor actor = Dali::Actor::New();
560
561   // Register a float property
562   Property::Index index = actor.RegisterProperty( "t", 0.0f );
563   Dali::Stage::GetCurrent().Add(actor);
564
565   {
566     //Create a LinearConstrainer
567     Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
568     SetupLinearConstrainerUniformProgress( linearConstrainer );
569
570     //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
571     Vector2 range( 0.0f, 1.0f );
572     linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
573
574     //Test that the constraint is correctly applied
575     actor.SetProperty(index,0.5f);
576     application.SendNotification();
577     application.Render(static_cast<unsigned int>(1.0f));
578
579     DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
580
581   }
582
583   //LinearConstrainer has been destroyed. Constraint in the actor should have been removed
584   actor.SetProperty(index,0.75f);
585   application.SendNotification();
586   application.Render(static_cast<unsigned int>(1.0f));
587
588   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
589
590   END_TEST;
591 }
592
593 int UtcLinearConstrainerRemove(void)
594 {
595   TestApplication application;
596
597   Dali::Actor actor = Dali::Actor::New();
598
599   // Register a float property
600   Property::Index index = actor.RegisterProperty( "t", 0.0f );
601   Dali::Stage::GetCurrent().Add(actor);
602
603   //Create a LinearConstrainer
604   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
605   SetupLinearConstrainerUniformProgress( linearConstrainer );
606
607   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
608   Vector2 range( 0.0f, 1.0f );
609   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
610
611   //Test that the constraint is correctly applied
612   actor.SetProperty(index,0.5f);
613   application.SendNotification();
614   application.Render(static_cast<unsigned int>(1.0f));
615
616   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
617
618   //Remove constraint
619   linearConstrainer.Remove( actor );
620   actor.SetProperty(index,0.75f);
621   application.SendNotification();
622   application.Render(static_cast<unsigned int>(1.0f));
623
624   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
625
626   END_TEST;
627 }
628
629 int UtcLinearConstrainerProperties(void)
630 {
631   TestApplication application;
632
633   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
634
635   Dali::Property::Array points;
636   points.Resize(3);
637   points[0] = 0.0f;
638   points[1] = 1.0f;
639   points[2] = 0.0f;
640   linearConstrainer.SetProperty( Dali::LinearConstrainer::Property::VALUE, points );
641
642   {
643     Property::Value value = linearConstrainer.GetProperty( Dali::LinearConstrainer::Property::VALUE );
644     Property::Array* array = value.GetArray();
645     DALI_TEST_CHECK( array );
646
647     const unsigned int noOfPoints = points.Size();
648     for( unsigned int i = 0; i < noOfPoints; ++i )
649     {
650       DALI_TEST_EQUALS( ( *array )[i].Get< float >(), points[i].Get< float >(), TEST_LOCATION );
651     }
652   }
653
654   {
655     Property::Value value = DevelHandle::GetCurrentProperty( linearConstrainer, Dali::LinearConstrainer::Property::VALUE );
656     Property::Array* array = value.GetArray();
657     DALI_TEST_CHECK( array );
658
659     const unsigned int noOfPoints = points.Size();
660     for( unsigned int i = 0; i < noOfPoints; ++i )
661     {
662       DALI_TEST_EQUALS( ( *array )[i].Get< Vector3 >(), points[i].Get< Vector3 >(), TEST_LOCATION );
663     }
664   }
665
666   points[0] = 0.0f;
667   points[1] = 0.25f;
668   points[2] = 1.0f;
669   linearConstrainer.SetProperty( Dali::LinearConstrainer::Property::PROGRESS, points );
670
671   {
672     Property::Value value = linearConstrainer.GetProperty( Dali::LinearConstrainer::Property::PROGRESS );
673     Property::Array* array = value.GetArray();
674     DALI_TEST_CHECK( array );
675
676     const unsigned int noOfPoints = points.Size();
677     for( unsigned int i = 0; i < noOfPoints; ++i )
678     {
679       DALI_TEST_EQUALS( ( *array )[i].Get< float >(), points[i].Get< float >(), TEST_LOCATION );
680     }
681   }
682
683   {
684     Property::Value value = DevelHandle::GetCurrentProperty( linearConstrainer, Dali::LinearConstrainer::Property::PROGRESS );
685     Property::Array* array = value.GetArray();
686     DALI_TEST_CHECK( array );
687
688     const unsigned int noOfPoints = points.Size();
689     for( unsigned int i = 0; i < noOfPoints; ++i )
690     {
691       DALI_TEST_EQUALS( ( *array )[i].Get< float >(), points[i].Get< float >(), TEST_LOCATION );
692     }
693   }
694
695   END_TEST;
696 }