+void LayoutController::PerformLayoutPositioning( LayoutPositionDataArray& layoutPositionDataArray, bool all ) const
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayoutPositioning %d\n", (int)all );
+
+ for( auto layoutPositionData : layoutPositionDataArray )
+ {
+ Actor actor = layoutPositionData.handle.GetHandle();
+ if( actor && ( !layoutPositionData.animated || all ) )
+ {
+ if( !layoutPositionData.animated )
+ {
+ actor.SetPosition( layoutPositionData.left, layoutPositionData.top );
+ actor.SetSize( layoutPositionData.right - layoutPositionData.left, layoutPositionData.bottom - layoutPositionData.top );
+ }
+ else
+ {
+ actor.SetPosition( actor.GetCurrentPosition() );
+ actor.SetSize( actor.GetCurrentSize() );
+ }
+ }
+ }
+}
+
+void LayoutController::PerformLayoutAnimation( LayoutTransition& layoutTransition, LayoutPositionDataArray& layoutPositionDataArray, LayoutDataArray& layoutDataArray, LayoutAnimatorArray& layoutAnimatorArray )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayoutAnimation\n" );
+ Animation animation = Animation::New( 0 );
+ bool isAnimatorAdded = false;
+
+ if( layoutAnimatorArray.size() == 0 )
+ {
+ layoutAnimatorArray.push_back( LayoutDataAnimator() );
+ }
+
+ for( auto layoutDataElement : layoutDataArray )
+ {
+ if( layoutDataElement.animatorIndex >= 0 )
+ {
+ Actor actor = layoutDataElement.handle.GetHandle();
+ if ( actor )
+ {
+ LayoutDataAnimator animator = layoutAnimatorArray[ layoutDataElement.animatorIndex ];
+ TimePeriod timePeriod = TimePeriod( 0, animation.GetDuration() );
+ if( animator.timePeriod.durationSeconds >= 0 )
+ {
+ timePeriod = animator.timePeriod;
+ }
+
+ Property::Value value = layoutDataElement.targetValue;
+ // Capture calculated position and size values after layout if target values are not set.
+ // Other values are set to current actor ones.
+ if( value.GetType() == Property::NONE )
+ {
+ if( layoutDataElement.positionDataIndex < 0)
+ {
+ auto result = std::find_if( layoutPositionDataArray.begin(), layoutPositionDataArray.end(), [&actor](const LayoutPositionData& iter)
+ { return iter.handle == actor; } );
+ if( result == layoutPositionDataArray.end() )
+ {
+ continue;
+ }
+ layoutDataElement.positionDataIndex = std::distance( layoutPositionDataArray.begin(), result );
+ }
+
+ LayoutPositionData& positionData = layoutPositionDataArray[ layoutDataElement.positionDataIndex ];
+ // with updated measured size scale animation the measured size includes scale, so we need to fit in the centre of the measured rectangle
+ // the real size child so that the all scale related animations placed correctly
+ if( positionData.updateWithCurrentSize )
+ {
+ Vector3 size = actor.GetCurrentSize();
+ float dX = ( ( positionData.right - positionData.left ) - size.width ) / 2;
+ float dY = ( ( positionData.bottom - positionData.top ) - size.height ) / 2;
+ positionData.left += dX;
+ positionData.top += dY;
+ positionData.right -= dX;
+ positionData.bottom -= dY;
+ positionData.updateWithCurrentSize = false;
+ }
+
+ switch ( layoutDataElement.propertyIndex )
+ {
+ case Actor::Property::POSITION:
+ value = Vector3( positionData.left, positionData.top, 0.0f );
+ break;
+ case Actor::Property::POSITION_X:
+ value = positionData.left;
+ break;
+ case Actor::Property::POSITION_Y:
+ value = positionData.top;
+ break;
+ case Actor::Property::SIZE:
+ value = Vector3( positionData.right - positionData.left, positionData.bottom - positionData.top, 0.0f );
+ break;
+ case Actor::Property::SIZE_WIDTH:
+ value = positionData.right - positionData.left;
+ break;
+ case Actor::Property::SIZE_HEIGHT:
+ value = positionData.bottom - positionData.top;
+ break;
+ default:
+ value = actor.GetProperty( layoutDataElement.propertyIndex );
+ }
+ }
+
+ // Failed to get target value, just move to the next one
+ if( value.GetType() == Property::NONE )
+ {
+ continue;
+ }
+
+ // Set initial value
+ Property::Value initialValue = layoutDataElement.initialValue;
+ if( initialValue.GetType() != Property::NONE )
+ {
+ actor.SetProperty( layoutDataElement.propertyIndex, initialValue );
+ }
+
+ // Create an animator for the property
+ switch( animator.animatorType )
+ {
+ case Toolkit::LayoutTransitionData::Animator::ANIMATE_TO:
+ {
+ animation.AnimateTo( Property( actor, layoutDataElement.propertyIndex ), value, animator.alphaFunction, timePeriod );
+ break;
+ }
+ case Toolkit::LayoutTransitionData::Animator::ANIMATE_BY:
+ {
+ animation.AnimateBy( Property( actor, layoutDataElement.propertyIndex ), value, animator.alphaFunction, timePeriod );
+ break;
+ }
+ case Toolkit::LayoutTransitionData::Animator::ANIMATE_BETWEEN:
+ {
+ animation.AnimateBetween( Property( actor, layoutDataElement.propertyIndex ), animator.keyFrames, animator.alphaFunction, animator.interpolation );
+ break;
+ }
+ case Toolkit::LayoutTransitionData::Animator::ANIMATE_PATH:
+ {
+ animation.Animate( actor, animator.path, animator.forward, animator.alphaFunction, timePeriod );
+ break;
+ }
+ }
+ isAnimatorAdded = true;
+ }
+ }
+ }
+
+ if( isAnimatorAdded )
+ {
+ if( mAnimation.GetState() == Animation::PLAYING )
+ {
+ mAnimation.SetCurrentProgress( 1.0f );
+ }
+ mAnimation = animation;
+ mAnimationFinishedFunctors.push_back( AnimationFinishedFunctor( *this, layoutTransition, layoutPositionDataArray ) );
+ mAnimation.FinishedSignal().Connect( mSlotDelegate.GetConnectionTracker(), mAnimationFinishedFunctors.back() );
+ mAnimation.Play();
+ }
+}