2 * Copyright (c) 2018 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.
17 #include <dali/integration-api/debug.h>
19 #include <dali/public-api/animation/animation.h>
20 #include <dali/public-api/object/base-handle.h>
21 #include <dali/public-api/object/type-registry-helper.h>
22 #include <dali-toolkit/public-api/controls/control.h>
23 #include <dali/devel-api/object/handle-devel.h>
24 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
25 #include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
26 #include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
27 #include <dali-toolkit/internal/layouting/layout-item-data-impl.h>
29 #include <dali/devel-api/scripting/enum-helper.h>
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_TYPE("type");
39 const char* TOKEN_NAME("name");
40 const char* TOKEN_TIME_PERIOD("timePeriod");
41 const char* TOKEN_DURATION("duration");
42 const char* TOKEN_DELAY("delay");
43 const char* TOKEN_ALPHA_FUNCTION("alphaFunction");
45 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALPHA_FUNCTION_BUILTIN )
46 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, LINEAR)
47 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, REVERSE)
48 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN)
49 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT)
50 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_OUT)
51 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_SQUARE)
52 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_SQUARE)
53 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_SINE)
54 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_SINE)
55 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_IN_OUT_SINE)
56 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, EASE_OUT_BACK)
57 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, BOUNCE)
58 DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::AlphaFunction, SIN)
59 DALI_ENUM_TO_STRING_TABLE_END( ALPHA_FUNCTION_BUILTIN )
70 LayoutTransitionData::LayoutTransitionData()
74 LayoutTransitionData::~LayoutTransitionData()
78 LayoutTransitionDataPtr LayoutTransitionData::New()
80 LayoutTransitionDataPtr layoutAnimationData( new LayoutTransitionData() );
81 return layoutAnimationData;
84 LayoutTransitionData::PropertyAnimator::PropertyAnimator( )
87 , interpolation( Animation::Linear )
91 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map )
94 , interpolation( Animation::Linear )
98 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward )
101 , interpolation( Animation::Linear )
107 LayoutTransitionData::PropertyAnimator::PropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation )
110 , keyFrames( keyFrames )
111 , interpolation( interpolation )
115 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map )
117 mPropertyAnimators.push_back( PropertyAnimator( actor, map ) );
120 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation )
122 mPropertyAnimators.push_back( PropertyAnimator( actor, map, keyFrames, interpolation ) );
125 void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward )
127 mPropertyAnimators.push_back( PropertyAnimator( actor, map, path, forward ) );
130 bool LayoutTransitionData::ConvertToLayoutAnimator( const Property::Map& animatorMap, const PropertyAnimator& propertyAnimator, LayoutDataAnimator& layoutDataAnimator )
134 for ( size_t animatorMapIdx = 0; animatorMapIdx < animatorMap.Count(); ++animatorMapIdx )
136 const KeyValuePair pair( animatorMap.GetKeyValue( animatorMapIdx ) );
138 Property::Index indexKey = Property::INVALID_INDEX;
139 if ( pair.first.type == Property::Key::STRING )
141 const std::string& key(pair.first.stringKey);
142 if( key == TOKEN_TYPE )
144 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE;
146 else if( key == TOKEN_NAME )
148 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::NAME;
150 else if( key == TOKEN_TIME_PERIOD )
152 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TIME_PERIOD;
154 else if( key == TOKEN_ALPHA_FUNCTION )
156 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION;
161 indexKey = pair.first.indexKey;
164 const Property::Value& value( pair.second );
166 if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION )
168 if ( value.GetType() == Property::ARRAY )
171 Vector4 controlPoints;
172 Property::Array *array = value.GetArray();
173 if ( array && array->Count() >= 4 )
175 for ( size_t vecIdx = 0; vecIdx < 4; ++vecIdx )
177 Property::Value& v = array->GetElementAt( vecIdx );
178 if ( v.GetType() == Property::FLOAT )
180 controlPoints[vecIdx] = v.Get<float>();
196 Vector2 controlPoint1( controlPoints.x, controlPoints.y );
197 Vector2 controlPoint2( controlPoints.z, controlPoints.w );
198 layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
205 else if ( value.GetType() == Property::VECTOR4 )
207 Vector4 controlPoints = value.Get<Vector4>();
208 Vector2 controlPoint1( controlPoints.x, controlPoints.y );
209 Vector2 controlPoint2( controlPoints.z, controlPoints.w );
210 layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
212 else if ( value.GetType() == Property::STRING )
214 std::string alphaFunctionValue = value.Get<std::string>();
216 if ( alphaFunctionValue == "LINEAR" )
218 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::LINEAR );
220 else if ( !alphaFunctionValue.compare( 0, 5, "EASE_" ) )
222 if ( alphaFunctionValue == "EASE_IN" )
224 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN );
226 else if ( alphaFunctionValue == "EASE_OUT" )
228 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT );
230 else if ( !alphaFunctionValue.compare( 5, 3, "IN_" ) )
232 if ( !alphaFunctionValue.compare( 8, -1, "SQUARE" ) )
234 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_SQUARE );
236 else if ( !alphaFunctionValue.compare( 8, -1, "OUT" ) )
238 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_OUT );
240 else if ( !alphaFunctionValue.compare( 8, -1, "OUT_SINE" ) )
242 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_OUT_SINE );
244 else if ( !alphaFunctionValue.compare( 8, -1, "SINE" ) )
246 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_IN_SINE );
249 else if ( !alphaFunctionValue.compare( 5, 4, "OUT_" ) )
251 if ( !alphaFunctionValue.compare( 9, -1, "SQUARE" ) )
253 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_SQUARE );
255 else if ( !alphaFunctionValue.compare( 9, -1, "SINE" ) )
257 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_SINE );
259 else if ( !alphaFunctionValue.compare( 9, -1, "BACK" ) )
261 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::EASE_OUT_BACK );
265 else if ( alphaFunctionValue == "REVERSE" )
267 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::REVERSE );
269 else if ( alphaFunctionValue == "BOUNCE" )
271 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::BOUNCE );
273 else if ( alphaFunctionValue == "SIN" )
275 layoutDataAnimator.alphaFunction = AlphaFunction( AlphaFunction::SIN );
287 else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::NAME )
289 if( value.GetType() == Property::STRING )
291 layoutDataAnimator.name = value.Get<std::string>();
294 else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TYPE )
296 if( value.GetType() == Property::STRING )
298 std::string animatorType = value.Get<std::string>();
299 if( animatorType == "ANIMATE_TO" )
301 layoutDataAnimator.animatorType = LayoutDataAnimator::AnimatorType::ANIMATE_TO;
303 else if( animatorType == "ANIMATE_BY" )
305 layoutDataAnimator.animatorType = LayoutDataAnimator::AnimatorType::ANIMATE_BY;
307 else if( animatorType == "ANIMATE_BETWEEN" )
309 layoutDataAnimator.animatorType = LayoutDataAnimator::AnimatorType::ANIMATE_BETWEEN;
310 layoutDataAnimator.keyFrames = propertyAnimator.keyFrames;
312 else if( animatorType == "ANIMATE_PATH" )
314 layoutDataAnimator.animatorType = LayoutDataAnimator::AnimatorType::ANIMATE_PATH;
315 layoutDataAnimator.path = propertyAnimator.path;
316 layoutDataAnimator.forward = propertyAnimator.forward;
320 else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TIME_PERIOD )
322 Property::Map timeMap = value.Get<Property::Map>();
323 for ( size_t timeMapIdx = 0; timeMapIdx < timeMap.Count(); ++timeMapIdx )
325 const KeyValuePair pair( timeMap.GetKeyValue( timeMapIdx ) );
326 indexKey = Property::INVALID_INDEX;
328 if ( pair.first.type == Property::Key::STRING)
330 const std::string& key( pair.first.stringKey );
331 if( key == TOKEN_DURATION )
333 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION;
335 else if( key == TOKEN_DELAY )
337 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::DELAY;
342 indexKey = pair.first.indexKey;
345 if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DELAY )
347 layoutDataAnimator.timePeriod.delaySeconds = pair.second.Get<float>();
349 else if ( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::DURATION )
351 layoutDataAnimator.timePeriod.durationSeconds = pair.second.Get<float>();
360 bool LayoutTransitionData::ConvertToLayoutDataElement( const PropertyAnimator& propertyAnimator, LayoutDataElement& layoutDataElement, LayoutData& layoutData )
362 const Property::Map& map = propertyAnimator.map;
363 bool propertyFound = false;
365 for( unsigned int mapIdx = 0; mapIdx < map.Count(); ++mapIdx )
367 const KeyValuePair pair( map.GetKeyValue( mapIdx ) );
368 const Property::Value& value( pair.second );
369 Property::Index indexKey = Property::INVALID_INDEX;
371 if ( pair.first.type == Property::Key::STRING )
373 const std::string& key( pair.first.stringKey );
374 if ( key == TOKEN_PROPERTY )
376 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY;
378 else if( key == TOKEN_INITIAL_VALUE )
380 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::INITIAL_VALUE;
382 else if( key == TOKEN_TARGET_VALUE )
384 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE;
386 else if( key == TOKEN_ANIMATOR )
388 indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR;
393 indexKey = pair.first.indexKey;
396 if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY )
398 if( value.GetType() == Property::STRING )
400 Actor actor = Actor::DownCast( layoutDataElement.handle );
401 layoutDataElement.propertyIndex = DevelHandle::GetPropertyIndex( actor, Property::Key( value.Get<std::string>() ) );
405 layoutDataElement.propertyIndex = value.Get<int>();
407 propertyFound = true;
409 else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::INITIAL_VALUE )
411 layoutDataElement.initialValue = value;
413 else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE )
415 layoutDataElement.targetValue = value;
417 else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR )
419 if( value.GetType() == Property::STRING )
421 std::string animatorName = value.Get<std::string>();
422 if ( animatorName.empty() )
424 layoutDataElement.animatorIndex = 0;
428 auto animator = std::find_if( layoutData.layoutAnimatorArray.begin(), layoutData.layoutAnimatorArray.end(), [&animatorName](const LayoutDataAnimator& iter) {
429 return (iter.name == animatorName); } );
430 if( animator != layoutData.layoutAnimatorArray.end() )
432 layoutDataElement.animatorIndex = std::distance( layoutData.layoutAnimatorArray.begin(), animator );
436 else if ( value.GetType() == Property::MAP )
438 Property::Map animatorMap = value.Get< Property::Map >();
439 LayoutDataAnimator layoutDataAnimator;
440 if( ConvertToLayoutAnimator( animatorMap, propertyAnimator, layoutDataAnimator ) )
442 layoutData.layoutAnimatorArray.push_back( layoutDataAnimator );
443 layoutDataElement.animatorIndex = layoutData.layoutAnimatorArray.size()-1;
449 return propertyFound;
452 void LayoutTransitionData::ConvertToLayoutDataElements( Actor owner, LayoutData& layoutData )
454 LayoutDataArray& layoutDataArray = layoutData.layoutDataArray;
455 // Add the children animators
456 for( const PropertyAnimator& iter : layoutData.childrenPropertyAnimators )
458 LayoutDataElement layoutDataElement;
459 layoutDataElement.handle = owner;
460 layoutDataElement.positionDataIndex = layoutData.layoutPositionDataArray.size() - 1;
462 if( ConvertToLayoutDataElement( iter, layoutDataElement, layoutData ) )
464 layoutDataArray.push_back( layoutDataElement );
468 // Add the transition animators
469 for( const PropertyAnimator& iter : mPropertyAnimators )
471 if( iter.handle == nullptr )
473 layoutData.childrenPropertyAnimators.push_back( iter );
477 LayoutDataElement layoutDataElement;
478 layoutDataElement.handle = iter.handle;
479 if( ConvertToLayoutDataElement( iter, layoutDataElement, layoutData ) )
481 layoutDataArray.push_back( layoutDataElement );
486 Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType& LayoutTransitionData::FinishedSignal()
488 return mFinishedSignal;
491 void LayoutTransitionData::EmitSignalFinish( int layoutTransitionType )
493 if ( !mFinishedSignal.Empty() )
495 Dali::Toolkit::LayoutTransitionData handle( this );
496 mFinishedSignal.Emit( static_cast<Dali::Toolkit::LayoutTransitionData::LayoutTransitionType>(layoutTransitionType), handle );
500 } // namespace Internal
501 } // namespace Toolkit