2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/visuals/transition-data-impl.h>
22 #include <dali-toolkit/public-api/controls/control-impl.h>
23 #include <dali-toolkit/public-api/controls/control.h>
24 #include <dali/dali.h>
25 #include <dali/devel-api/scripting/enum-helper.h>
26 #include <dali/integration-api/debug.h>
33 const char* TOKEN_TARGET("target");
34 const char* TOKEN_PROPERTY("property");
35 const char* TOKEN_INITIAL_VALUE("initialValue");
36 const char* TOKEN_TARGET_VALUE("targetValue");
37 const char* TOKEN_ANIMATOR("animator");
38 const char* TOKEN_TIME_PERIOD("timePeriod");
39 const char* TOKEN_DURATION("duration");
40 const char* TOKEN_DELAY("delay");
41 const char* TOKEN_ALPHA_FUNCTION("alphaFunction");
43 DALI_ENUM_TO_STRING_TABLE_BEGIN(ALPHA_FUNCTION_BUILTIN)
44 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, LINEAR)
45 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, REVERSE)
46 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN)
47 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT)
48 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_OUT)
49 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_SQUARE)
50 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_SQUARE)
51 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_SINE)
52 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_SINE)
53 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_OUT_SINE)
54 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_BACK)
55 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, BOUNCE)
56 DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, SIN)
57 DALI_ENUM_TO_STRING_TABLE_END(ALPHA_FUNCTION_BUILTIN)
68 /// Parses a Property::Array and sets up the animator appropriately
69 void ParseArray(TransitionData::Animator* animator, const Property::Array* array)
72 Vector4 controlPoints;
73 if(array && array->Count() >= 4)
75 for(size_t vecIdx = 0; vecIdx < 4; ++vecIdx)
77 const Property::Value& v = array->GetElementAt(vecIdx);
78 if(v.GetType() == Property::FLOAT)
80 controlPoints[vecIdx] = v.Get<float>();
96 Vector2 controlPoint1(controlPoints.x, controlPoints.y);
97 Vector2 controlPoint2(controlPoints.z, controlPoints.w);
98 animator->alphaFunction = AlphaFunction(controlPoint1, controlPoint2);
102 animator->animate = false;
106 /// Parses a string value and sets up the animator appropriately
107 void ParseString(TransitionData::Animator* animator, std::string alphaFunctionValue)
109 if(alphaFunctionValue == "LINEAR")
111 animator->alphaFunction = AlphaFunction(AlphaFunction::LINEAR);
113 else if(!alphaFunctionValue.compare(0, 5, "EASE_"))
115 if(alphaFunctionValue == "EASE_IN")
117 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN);
119 else if(alphaFunctionValue == "EASE_OUT")
121 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT);
123 else if(!alphaFunctionValue.compare(5, 3, "IN_"))
125 if(!alphaFunctionValue.compare(8, -1, "SQUARE"))
127 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SQUARE);
129 else if(!alphaFunctionValue.compare(8, -1, "OUT"))
131 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT);
133 else if(!alphaFunctionValue.compare(8, -1, "OUT_SINE"))
135 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT_SINE);
137 else if(!alphaFunctionValue.compare(8, -1, "SINE"))
139 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SINE);
142 else if(!alphaFunctionValue.compare(5, 4, "OUT_"))
144 if(!alphaFunctionValue.compare(9, -1, "SQUARE"))
146 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SQUARE);
148 else if(!alphaFunctionValue.compare(9, -1, "SINE"))
150 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SINE);
152 else if(!alphaFunctionValue.compare(9, -1, "BACK"))
154 animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_BACK);
158 else if(alphaFunctionValue == "REVERSE")
160 animator->alphaFunction = AlphaFunction(AlphaFunction::REVERSE);
162 else if(alphaFunctionValue == "BOUNCE")
164 animator->alphaFunction = AlphaFunction(AlphaFunction::BOUNCE);
166 else if(alphaFunctionValue == "SIN")
168 animator->alphaFunction = AlphaFunction(AlphaFunction::SIN);
171 } // unnamed namespace
173 TransitionData::TransitionData()
177 TransitionData::~TransitionData()
181 TransitionDataPtr TransitionData::New(const Property::Array& value)
183 TransitionDataPtr transitionData(new TransitionData());
184 transitionData->Initialize(value);
185 return transitionData;
188 TransitionDataPtr TransitionData::New(const Property::Map& value)
190 TransitionDataPtr transitionData(new TransitionData());
191 transitionData->Initialize(value);
192 return transitionData;
195 void TransitionData::Initialize(const Property::Map& map)
197 TransitionData::Animator* animator = ConvertMap(map);
201 void TransitionData::Initialize(const Property::Array& array)
203 for(unsigned int arrayIdx = 0, transitionArrayCount = array.Count(); arrayIdx < transitionArrayCount; ++arrayIdx)
205 const Property::Value& element = array.GetElementAt(arrayIdx);
206 // Expect each child to be an object representing an animator:
208 const Property::Map* map = element.GetMap();
211 TransitionData::Animator* animator = ConvertMap(*map);
217 TransitionData::Animator* TransitionData::ConvertMap(const Property::Map& map)
219 TransitionData::Animator* animator = new TransitionData::Animator();
220 animator->alphaFunction = AlphaFunction::LINEAR;
221 animator->timePeriodDelay = 0.0f;
222 animator->timePeriodDuration = 1.0f;
224 for(unsigned int mapIdx = 0; mapIdx < map.Count(); ++mapIdx)
226 const KeyValuePair pair(map.GetKeyValue(mapIdx));
227 if(pair.first.type == Property::Key::INDEX)
229 continue; // We don't consider index keys.
232 const std::string& key(pair.first.stringKey);
233 const Property::Value& value(pair.second);
235 if(key == TOKEN_TARGET)
237 animator->objectName = value.Get<std::string>();
239 else if(key == TOKEN_PROPERTY)
241 if(value.GetType() == Property::STRING)
243 animator->propertyKey = Property::Key(value.Get<std::string>());
247 animator->propertyKey = Property::Key(value.Get<int>());
250 else if(key == TOKEN_INITIAL_VALUE)
252 animator->initialValue = value;
254 else if(key == TOKEN_TARGET_VALUE)
256 animator->targetValue = value;
258 else if(key == TOKEN_ANIMATOR)
260 animator->animate = true;
261 Property::Map animatorMap = value.Get<Property::Map>();
262 for(size_t animatorMapIdx = 0; animatorMapIdx < animatorMap.Count(); ++animatorMapIdx)
264 const KeyValuePair pair(animatorMap.GetKeyValue(animatorMapIdx));
266 if(pair.first.type == Property::Key::INDEX)
268 continue; // We don't consider index keys.
271 const std::string& key(pair.first.stringKey);
272 const Property::Value& value(pair.second);
274 if(key == TOKEN_ALPHA_FUNCTION)
276 if(value.GetType() == Property::ARRAY)
278 ParseArray(animator, value.GetArray());
280 else if(value.GetType() == Property::VECTOR4)
282 Vector4 controlPoints = value.Get<Vector4>();
283 Vector2 controlPoint1(controlPoints.x, controlPoints.y);
284 Vector2 controlPoint2(controlPoints.z, controlPoints.w);
285 animator->alphaFunction = AlphaFunction(controlPoint1, controlPoint2);
287 else if(value.GetType() == Property::STRING)
289 ParseString(animator, value.Get<std::string>());
293 animator->animate = false;
296 else if(key == TOKEN_TIME_PERIOD)
298 Property::Map timeMap = value.Get<Property::Map>();
299 for(size_t timeMapIdx = 0; timeMapIdx < timeMap.Count(); ++timeMapIdx)
301 const KeyValuePair pair(timeMap.GetKeyValue(timeMapIdx));
302 if(pair.first.type == Property::Key::INDEX)
306 const std::string& key(pair.first.stringKey);
308 if(key == TOKEN_DELAY)
310 animator->timePeriodDelay = pair.second.Get<float>();
312 else if(key == TOKEN_DURATION)
314 animator->timePeriodDuration = pair.second.Get<float>();
324 void TransitionData::Add(Animator* animator)
326 mAnimators.PushBack(animator);
329 TransitionData::Iterator TransitionData::Begin() const
331 return mAnimators.Begin();
334 TransitionData::Iterator TransitionData::End() const
336 return mAnimators.End();
339 size_t TransitionData::Count() const
341 return mAnimators.Count();
344 Property::Map TransitionData::GetAnimatorAt(size_t index)
346 DALI_ASSERT_ALWAYS(index < Count() && "index exceeds bounds");
348 Animator* animator = mAnimators[index];
350 map[TOKEN_TARGET] = animator->objectName;
351 if(animator->propertyKey.type == Property::Key::INDEX)
353 map[TOKEN_PROPERTY] = animator->propertyKey.indexKey;
357 map[TOKEN_PROPERTY] = animator->propertyKey.stringKey;
359 if(animator->initialValue.GetType() != Property::NONE)
361 map[TOKEN_INITIAL_VALUE] = animator->initialValue;
363 if(animator->targetValue.GetType() != Property::NONE)
365 map[TOKEN_TARGET_VALUE] = animator->targetValue;
367 if(animator->animate)
369 Property::Map animateMap;
371 if(animator->alphaFunction.GetMode() == AlphaFunction::BUILTIN_FUNCTION)
373 animateMap.Add(TOKEN_ALPHA_FUNCTION, GetEnumerationName(animator->alphaFunction.GetBuiltinFunction(), ALPHA_FUNCTION_BUILTIN_TABLE, ALPHA_FUNCTION_BUILTIN_TABLE_COUNT));
375 else if(animator->alphaFunction.GetMode() == AlphaFunction::BEZIER)
377 Vector4 controlPoints = animator->alphaFunction.GetBezierControlPoints();
378 animateMap.Add(TOKEN_ALPHA_FUNCTION, controlPoints);
380 animateMap.Add(TOKEN_TIME_PERIOD, Property::Map().Add(TOKEN_DELAY, animator->timePeriodDelay).Add(TOKEN_DURATION, animator->timePeriodDuration));
382 map[TOKEN_ANIMATOR] = animateMap;
388 } // namespace Internal
389 } // namespace Toolkit