X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Flayouting%2Flayout-controller-impl.cpp;h=d2e0119de78e2e501e7107b709585ee3660e28dd;hp=f912810a317f322fd99a2be5cf347f8f5648d9c5;hb=fe706c2b9e0a2ce31c91317dd6749faecef6d92e;hpb=7098ad0a9a657b68b37d5fd759662a2d08b47433 diff --git a/dali-toolkit/internal/layouting/layout-controller-impl.cpp b/dali-toolkit/internal/layouting/layout-controller-impl.cpp index f912810..d2e0119 100644 --- a/dali-toolkit/internal/layouting/layout-controller-impl.cpp +++ b/dali-toolkit/internal/layouting/layout-controller-impl.cpp @@ -17,11 +17,13 @@ #include #include #include +#include #include #include #include #include #include +#include using namespace Dali; @@ -42,7 +44,9 @@ namespace Internal { LayoutController::LayoutController() -: mLayoutRequested(false) +: mLayoutRequested( false ), + mFocusChangedFunctor( *this ), + mSlotDelegate( this ) { } @@ -52,15 +56,52 @@ LayoutController::~LayoutController() void LayoutController::Initialize() { + mAnimation = Animation::New( 0.0f ); + + Dali::Toolkit::KeyInputFocusManager manager = Dali::Toolkit::KeyInputFocusManager::Get(); + manager.KeyInputFocusChangedSignal().Connect( mSlotDelegate.GetConnectionTracker(), mFocusChangedFunctor ); +} + +void LayoutController::FocusChangedFunctor::operator() ( Dali::Toolkit::Control gainingControl, Dali::Toolkit::Control lostControl ) +{ + Toolkit::LayoutItem layoutItem = Toolkit::DevelControl::GetLayout( gainingControl ); + if( layoutItem ) + { + Toolkit::Internal::LayoutItem& layoutItemImpl = GetImplementation( layoutItem ); + LayoutParent* layoutParent = layoutItemImpl.GetParent(); + if( layoutParent ) + { + LayoutGroup* layoutGroup = static_cast< LayoutGroup* >( layoutParent ); + layoutController.RequestLayout( dynamic_cast< Toolkit::Internal::LayoutItem& >( *layoutGroup ), Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS, gainingControl, lostControl ); + } + } } -void LayoutController::RequestLayout( LayoutItem& LayoutItem ) +void LayoutController::RequestLayout( LayoutItem& layoutItem, int layoutTransitionType, Actor gainedChild, Actor lostChild ) { - DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout\n" ); + auto actor = Actor::DownCast( layoutItem.GetOwner() ); + if ( actor ) + { + DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout owner[%s] layoutItem[%p] layoutTransitionType(%d)\n", actor.GetName().c_str(), &layoutItem, layoutTransitionType ); + } + else + { + DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout layoutItem[%p] layoutAnimationType(%d)\n", &layoutItem, layoutTransitionType ); + } + mLayoutRequested = true; + if( layoutTransitionType != -1 ) + { + LayoutTransition layoutTransition = LayoutTransition( layoutItem, layoutTransitionType, gainedChild, lostChild ); + if( std::find( mLayoutTransitions.begin(), mLayoutTransitions.end(), layoutTransition ) == mLayoutTransitions.end() && layoutItem.GetTransitionData( layoutTransitionType ).Get() ) + { + DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout Add transition layoutTransitionType(%d)\n", layoutTransitionType ); + mLayoutTransitions.push_back( layoutTransition ); + } + } // Go up the tree and mark all parents to relayout - LayoutParent* layoutParent = LayoutItem.GetParent(); + LayoutParent* layoutParent = layoutItem.GetParent(); if( layoutParent ) { LayoutGroup& layoutGroup = static_cast< LayoutGroup& >( *layoutParent ); @@ -74,11 +115,10 @@ void LayoutController::RequestLayout( LayoutItem& LayoutItem ) void LayoutController::Process() { // Perform the full process. + DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::Process\n" ); if( mLayoutRequested ) { - mLayoutRequested = false; - // If window size has changed, expect stage to have already been updated Stage stage = Stage::GetCurrent(); auto stageWidth = stage.GetSize().width; @@ -91,8 +131,34 @@ void LayoutController::Process() MeasureHierarchy( stage.GetRootLayer(), widthSpec, heightSpec ); LAYOUT_DEBUG_MEASURE_STATES( stage.GetRootLayer() ); + + LayoutTransition layoutTransition; + LayoutPositionDataArray layoutPositionDataArray; + LayoutDataArray layoutDataArray; + LayoutAnimatorArray layoutAnimatorArray; + layoutAnimatorArray.push_back( LayoutDataAnimator() ); + PropertyAnimatorArray childrenPropertiesAnimators; + + if ( mLayoutTransitions.size() ) + { + layoutTransition = mLayoutTransitions.front(); + mLayoutTransitions.pop_front(); + mLayoutRequested = ( mLayoutTransitions.size() != 0 ); + } + else + { + mLayoutRequested = false; + } + + LayoutData layoutData( layoutTransition, layoutPositionDataArray, layoutDataArray, layoutAnimatorArray, childrenPropertiesAnimators ); + LayoutItem::Impl::sLayoutData = &layoutData; PerformLayout( stage.GetRootLayer(), 0, 0, stageWidth, stageHeight ); + PerformLayoutPositioning( layoutPositionDataArray, false ); + + PerformLayoutAnimation( layoutTransition, layoutPositionDataArray, layoutDataArray, layoutAnimatorArray ); + LayoutItem::Impl::sLayoutData = nullptr; + LAYOUT_DEBUG_AFTER_LAYOUT( stage.GetRootLayer() ); } } @@ -145,7 +211,6 @@ void LayoutController::PerformLayout( Actor root, int left, int top, int right, if( layout ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayout on layout\n" ); layout->Layout( left, top, right, bottom ); } } @@ -161,6 +226,145 @@ void LayoutController::PerformLayout( Actor root, int left, int top, int right, } } +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 = Actor::DownCast( layoutPositionData.handle ); + if( actor && ( !layoutPositionData.animated || all ) ) + { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayoutPositioning %s\n", actor.GetName().c_str() ); + 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; + + for( auto layoutDataElement : layoutDataArray ) + { + if ( layoutDataElement.animatorIndex >= 0 ) + { + Actor actor = Actor::DownCast( layoutDataElement.handle ); + 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 ]; + + 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 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 LayoutDataAnimator::AnimatorType::ANIMATE_TO: + { + animation.AnimateTo( Property( actor, layoutDataElement.propertyIndex ), value, animator.alphaFunction, timePeriod ); + break; + } + case LayoutDataAnimator::AnimatorType::ANIMATE_BY: + { + animation.AnimateBy( Property( actor, layoutDataElement.propertyIndex ), value, animator.alphaFunction, timePeriod ); + break; + } + case LayoutDataAnimator::AnimatorType::ANIMATE_BETWEEN: + { + animation.AnimateBetween( Property( actor, layoutDataElement.propertyIndex ), animator.keyFrames, animator.alphaFunction, animator.interpolation ); + break; + } + case LayoutDataAnimator::AnimatorType::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(); + } +} } // namespace Internal } // namespace Toolkit