Merge "Clean up the code to build successfully on macOS" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / path-constrainer-impl.cpp
1 /*
2  * Copyright (c) 2018 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 // CLASS HEADER
19 #include <dali/internal/event/animation/path-constrainer-impl.h>
20
21 //EXTRENAL INCLUDES
22 #include <cstring> // for strcmp
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/animation/constraint.h>
26 #include <dali/public-api/object/property-array.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/internal/event/common/property-helper.h>
29
30 namespace Dali
31 {
32
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 // Properties
40 //              Name             Type   writable animatable constraint-input  enum for index-checking
41 DALI_PROPERTY_TABLE_BEGIN
42 DALI_PROPERTY( "forward",       VECTOR3,   true,    false,       false,        Dali::PathConstrainer::Property::FORWARD )
43 DALI_PROPERTY( "points",         ARRAY,    true,    false,       false,        Dali::PathConstrainer::Property::POINTS )
44 DALI_PROPERTY( "controlPoints",  ARRAY,    true,    false,       false,        Dali::PathConstrainer::Property::CONTROL_POINTS )
45 DALI_PROPERTY_TABLE_END( DEFAULT_OBJECT_PROPERTY_START_INDEX, PathConstrainerDefaultProperties )
46
47 BaseHandle Create()
48 {
49   return Dali::PathConstrainer::New();
50 }
51
52 TypeRegistration mType( typeid( Dali::PathConstrainer ), typeid( Dali::Handle ), Create, PathConstrainerDefaultProperties );
53
54 } //Unnamed namespace
55
56 PathConstrainer* PathConstrainer::New()
57 {
58   return new PathConstrainer();
59 }
60
61 PathConstrainer::PathConstrainer()
62 : Constrainer(),
63   mPath( Path::New() )
64 {
65 }
66
67 PathConstrainer::~PathConstrainer() = default;
68
69 Property::Value PathConstrainer::GetDefaultProperty( Property::Index index ) const
70 {
71   if( index == Dali::PathConstrainer::Property::FORWARD )
72   {
73     return Property::Value( mForward );
74   }
75   else
76   {
77     if( index == Dali::PathConstrainer::Property::POINTS )
78     {
79       Property::Value value( Property::ARRAY );
80       Property::Array* array = value.GetArray();
81       const Dali::Vector<Vector3>& point = mPath->GetPoints();
82       Property::Array::SizeType pointCount = static_cast<Property::Array::SizeType>( point.Size() );
83
84       if( array )
85       {
86         array->Reserve( pointCount );
87         for( Property::Array::SizeType i = 0; i < pointCount; ++i )
88         {
89           array->PushBack( point[i] );
90         }
91       }
92       return value;
93     }
94     else if( index == Dali::PathConstrainer::Property::CONTROL_POINTS )
95     {
96       Property::Value value( Property::ARRAY );
97       Property::Array* array = value.GetArray();
98       const Dali::Vector<Vector3>& point = mPath->GetControlPoints();
99       Property::Array::SizeType pointCount = static_cast<Property::Array::SizeType>( point.Size() );
100
101       if( array )
102       {
103         array->Reserve( pointCount );
104         for( Property::Array::SizeType i = 0; i < pointCount; ++i )
105         {
106           array->PushBack( point[i] );
107         }
108       }
109       return value;
110     }
111   }
112
113   return Property::Value();
114 }
115
116 Property::Value PathConstrainer::GetDefaultPropertyCurrentValue( Property::Index index ) const
117 {
118   return GetDefaultProperty( index ); // Event-side only properties
119 }
120
121 void PathConstrainer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
122 {
123   if( index == Dali::PathConstrainer::Property::FORWARD )
124   {
125     propertyValue.Get(mForward);
126   }
127   else if( index == Dali::PathConstrainer::Property::POINTS  )
128   {
129     const Property::Array* array = propertyValue.GetArray();
130     mPath->ClearPoints();
131     if( array )
132     {
133       for( Property::Array::SizeType i = 0, count = array->Count(); i < count; ++i )
134       {
135         Vector3 point;
136         array->GetElementAt( i ).Get( point );
137         mPath->AddPoint( point );
138       }
139     }
140   }
141   else if( index == Dali::PathConstrainer::Property::CONTROL_POINTS )
142   {
143     const Property::Array* array = propertyValue.GetArray();
144     mPath->ClearControlPoints();
145     if( array )
146     {
147       for( Property::Array::SizeType i = 0, count = array->Count(); i < count; ++i )
148       {
149         Vector3 point;
150         array->GetElementAt( i ).Get( point );
151         mPath->AddControlPoint( point );
152       }
153     }
154   }
155 }
156
157 void PathConstrainer::Apply( Property target, Property source, const Vector2& range, const Vector2& wrap)
158 {
159   Dali::Property::Type propertyType = target.object.GetPropertyType( target.propertyIndex);
160   if( propertyType == Dali::Property::VECTOR3)
161   {
162     // If property type is Vector3, constrain its value to the position of the path
163     Dali::Constraint constraint = Dali::Constraint::New<Vector3>( target.object, target.propertyIndex, PathConstraintFunctor( mPath, range, wrap ) );
164     constraint.AddSource( Dali::Source(source.object, source.propertyIndex ) );
165
166     constraint.SetTag( static_cast<uint32_t>( reinterpret_cast<uintptr_t>( this ) ) ); // taking 32bits of this as tag
167     constraint.SetRemoveAction( Dali::Constraint::DISCARD );
168     constraint.Apply();
169   }
170   else if( propertyType == Dali::Property::ROTATION )
171   {
172     // If property type is Rotation, constrain its value to align the forward vector to the tangent of the path
173     Dali::Constraint constraint = Dali::Constraint::New<Quaternion>( target.object, target.propertyIndex, PathConstraintFunctor( mPath, range, mForward, wrap) );
174     constraint.AddSource( Dali::Source(source.object, source.propertyIndex ) );
175
176     constraint.SetTag( static_cast<uint32_t>( reinterpret_cast<uintptr_t>( this ) ) ); // taking 32bits of this as tag
177     constraint.SetRemoveAction( Dali::Constraint::DISCARD );
178     constraint.Apply();
179   }
180
181   //Start observing the object
182   Observe( target.object );
183 }
184
185 } // Internal
186
187 } // Dali