X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Fdevel-api%2Flayouting%2Flayout-item-impl.cpp;h=fe26362886470d099f28563748beb000b4436da8;hp=5336a7f30e4428c0069026987afbee665d2ce738;hb=118f87dfe57967bfed8ccdf9143a078eaef1b119;hpb=50000cb0936f21b4577085f3a348254f3895d377 diff --git a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp index 5336a7f..fe26362 100644 --- a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp @@ -19,20 +19,24 @@ #include #include #include +#include #include +#include +#include #include +#include + namespace { #if defined(DEBUG_ENABLED) -Debug::Filter* gLayoutFilter = Debug::Filter::New( Debug::Verbose, false, "LOG_LAYOUT" ); +Debug::Filter* gLayoutFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" ); #endif const char* WIDTH_SPECIFICATION_NAME( "widthSpecification" ); const char* HEIGHT_SPECIFICATION_NAME( "heightSpecification" ); -const float DEFAULT_TRANSITION_DURATION( 0.5f ); } namespace Dali @@ -65,7 +69,6 @@ void LayoutItem::Initialize( Handle& owner, const std::string& containerType ) mImpl->mOwner = &(owner.GetBaseObject()); RegisterChildProperties( containerType ); OnInitialize(); // Ensure direct deriving class gets initialized - RequestLayout(); } Handle LayoutItem::GetOwner() const @@ -78,13 +81,60 @@ void LayoutItem::Unparent() // Enable directly derived types to first remove children OnUnparent(); + // Remove myself from parent + LayoutParent* parent = GetParent(); + if( parent ) + { + parent->Remove( *this ); + } + + // Remove parent reference + SetParent(nullptr); + // Last, clear owner mImpl->mOwner = NULL; } +LayoutTransitionDataPtr LayoutItem::GetDefaultTransition() +{ + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultTransition\n" ); + if ( !mImpl->mDefaultTransitionData.Get() ) + { + auto owner = GetOwner(); + auto actor = Actor::DownCast( owner ); + + mImpl->mDefaultTransitionData = LayoutTransitionData::New(); + { + Property::Map map; + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR ] = std::string(); // default animator with default duration + // Capture calculated position after layout, apply default linear animation + mImpl->mDefaultTransitionData->AddPropertyAnimator( actor, map ); + } + { + Property::Map map; + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update + map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR ] = std::string(); // default animator with default duration + // Capture calculated size after layout, apply default linear animation + mImpl->mDefaultTransitionData->AddPropertyAnimator( actor, map ); + } + } + return mImpl->mDefaultTransitionData; +} + void LayoutItem::SetAnimateLayout( bool animateLayout ) { + auto owner = GetOwner(); + auto actor = Actor::DownCast(owner); + + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetAnimateLayout animateLayout(%s) owner(%s)\n", (animateLayout)?"true":"false", + ( ( Actor::DownCast( owner) ) ? Actor::DownCast(owner).GetName().c_str() : "Invalid Actor" ) ); + mImpl->mAnimated = animateLayout; + + OnAnimationStateChanged( animateLayout ); } bool LayoutItem::IsLayoutAnimated() const @@ -92,6 +142,49 @@ bool LayoutItem::IsLayoutAnimated() const return mImpl->mAnimated; } +void LayoutItem::SetTransitionData( int layoutTransitionType, Internal::LayoutTransitionDataPtr layoutTransitionDataPtr ) +{ + switch ( layoutTransitionType ) + { + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD: + mImpl->mOnChildAddTransitionData = layoutTransitionDataPtr; + break; + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE: + mImpl->mOnChildRemoveTransitionData = layoutTransitionDataPtr; + break; + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS: + mImpl->mOnChildFocusTransitionData = layoutTransitionDataPtr; + break; + case Dali::Toolkit::LayoutTransitionData::ON_OWNER_SET: + mImpl->mOnOwnerSetTransitionData = layoutTransitionDataPtr; + break; + case Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE: + mImpl->mOnLayoutChangeTransitionData = layoutTransitionDataPtr; + break; + default: + break; + } +} + +Internal::LayoutTransitionDataPtr LayoutItem::GetTransitionData( int layoutTransitionType ) const +{ + switch ( layoutTransitionType ) + { + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD: + return mImpl->mOnChildAddTransitionData.Get(); + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE: + return mImpl->mOnChildRemoveTransitionData.Get(); + case Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS: + return mImpl->mOnChildFocusTransitionData.Get(); + case Dali::Toolkit::LayoutTransitionData::ON_OWNER_SET: + return mImpl->mOnOwnerSetTransitionData.Get(); + case Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE: + return mImpl->mOnLayoutChangeTransitionData.Get(); + default: + return LayoutTransitionDataPtr(); + } +} + void LayoutItem::RegisterChildProperties( const std::string& containerType ) { // Call on derived types @@ -140,6 +233,12 @@ void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasur const bool needsLayout = specChanged && ( !isSpecExactly || !matchesSpecSize ); + DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::Measure("<ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET ); @@ -148,14 +247,14 @@ void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasur #if defined(DEBUG_ENABLED) std::ostringstream o; o<ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT ); // flag not set, setMeasuredDimension() was not invoked, we raise an exception to warn the developer DALI_ASSERT_ALWAYS( mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET ) && - "Layout's OnMeasure() did not set the measured dimension by calling setMeasuredDimension()" ); + "Layout's OnMeasure() Measured dimension flag not set" ); mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED ); } @@ -165,20 +264,31 @@ void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasur void LayoutItem::Layout( LayoutLength l, LayoutLength t, LayoutLength r, LayoutLength b ) { + DALI_LOG_TRACE_METHOD( gLayoutFilter ); + if( mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT ) ) { OnMeasure( mImpl->mOldWidthMeasureSpec, mImpl->mOldHeightMeasureSpec ); mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT ); } + LayoutData& layoutData = *mImpl->sLayoutData; + size_t size = layoutData.childrenLayoutDataArray.size(); + bool changed = SetFrame( l, t, r, b ); if( changed || mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED ) ) { + OnLayout( changed, l, t, r, b ); mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED ); } + if ( size != layoutData.childrenLayoutDataArray.size() ) + { + layoutData.childrenLayoutDataArray.resize( size ); + } + mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_IS_LAID_OUT ); } @@ -212,7 +322,7 @@ Extents LayoutItem::GetPadding() const { Extents padding = control.GetProperty( Toolkit::Control::Property::PADDING ); - DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutBase::Padding for %s : (%d,%d,%d,%d) \n", + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::Padding for %s : (%d,%d,%d,%d) \n", control.GetName().c_str(), padding.start, padding.end, padding.top, padding.bottom ); @@ -243,6 +353,8 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS auto specMode = measureSpec.GetMode(); auto specSize = measureSpec.GetSize(); + DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultSize MeasureSpec("< LayoutLength( 0 ) ) { result = size; } @@ -269,11 +385,15 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS break; } } + DALI_LOG_STREAM( gLayoutFilter, Debug::General, "LayoutItem::GetDefaultSize setting default size:" << result << "\n" ); return result; } void LayoutItem::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec) { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::OnMeasure\n"); + + // GetDefaultSize will limit the MeasureSpec to the suggested minimumWidth and minimumHeight SetMeasuredDimensions( GetDefaultSize( GetSuggestedMinimumWidth(), widthMeasureSpec ), GetDefaultSize( GetSuggestedMinimumHeight(), heightMeasureSpec ) ); } @@ -282,6 +402,12 @@ void LayoutItem::OnLayout( bool changed, LayoutLength left, LayoutLength top, La { } +void LayoutItem::SetParent( LayoutParent* parent ) +{ + mImpl->mLayoutParent = parent; + mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME ); +} + LayoutParent* LayoutItem::GetParent() { return mImpl->mLayoutParent; @@ -290,14 +416,43 @@ LayoutParent* LayoutItem::GetParent() void LayoutItem::RequestLayout() { Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner ); + if( control ) + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s)\n", + control.GetName().c_str() ); + } + // @todo Enforce failure if called in Measure/Layout passes. + mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); + Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get(); + layoutController.RequestLayout( Toolkit::LayoutItem( this ) ); +} + +void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutAnimationType ) +{ + Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner ); if ( control ) { - DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout %s\n", control.GetName().c_str()); + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s) layoutTranstionType(%d)\n", + control.GetName().c_str(), (int)layoutAnimationType ); } // @todo Enforce failure if called in Measure/Layout passes. mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get(); - layoutController.RequestLayout( Toolkit::LayoutItem(this) ); + layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType ); +} + +void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutAnimationType, Actor gainedChild, Actor lostChild ) +{ + Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner ); + if ( control ) + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s) layoutTranstionType(%d)\n", + control.GetName().c_str(), (int)layoutAnimationType ); + } + // @todo Enforce failure if called in Measure/Layout passes. + mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); + Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get(); + layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType, gainedChild, lostChild ); } bool LayoutItem::IsLayoutRequested() const @@ -307,15 +462,31 @@ bool LayoutItem::IsLayoutRequested() const void LayoutItem::SetLayoutRequested() { - return mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); + mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); +} + +bool LayoutItem::IsResizePolicyRequired() const +{ + return mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY ); +} + +void LayoutItem::SetResizePolicyRequired( bool resizePolicyRequired ) +{ + if( resizePolicyRequired ) + { + mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY ); + } + else + { + mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY ); + } } void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight ) { - DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutBase::SetMeasuredDimensions width(%d) height(%d) \n", - MeasureSpec::IntType( measuredWidth.GetSize() ), - MeasureSpec::IntType( measuredHeight.GetSize() ) - ); + + DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetMeasuredDimensions width(" << measuredWidth.GetSize() << ") height(" << measuredHeight.GetSize() << ") Control:" << + ( ( Actor::DownCast( GetOwner()) ) ? Actor::DownCast(GetOwner()).GetName().c_str() : "Invalid Actor" ) << "\n" ); mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET ); mImpl->mMeasuredWidth = measuredWidth; @@ -325,7 +496,7 @@ void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize LayoutLength LayoutItem::GetMeasuredWidth() const { // Get the size portion of the measured width - return mImpl->mMeasuredWidth.GetSize(); + return mImpl->mMeasuredWidth.GetSize(); } LayoutLength LayoutItem::GetMeasuredHeight() const @@ -349,7 +520,7 @@ LayoutLength LayoutItem::GetSuggestedMinimumWidth() const auto actor = Actor::DownCast(owner); auto naturalSize = actor ? actor.GetNaturalSize() : Vector3::ZERO; - return std::max( mImpl->mMinimumSize.GetWidth(), LayoutLength::IntType( naturalSize.width ) ); + return std::max( mImpl->mMinimumSize.GetWidth(), LayoutLength( naturalSize.width ) ); } LayoutLength LayoutItem::GetSuggestedMinimumHeight() const @@ -358,7 +529,7 @@ LayoutLength LayoutItem::GetSuggestedMinimumHeight() const auto actor = Actor::DownCast(owner); auto naturalSize = actor ? actor.GetNaturalSize() : Vector3::ZERO; - return std::max( mImpl->mMinimumSize.GetHeight(), LayoutLength::IntType(naturalSize.height) ); + return std::max( mImpl->mMinimumSize.GetHeight(), LayoutLength( naturalSize.height ) ); } MeasuredSize LayoutItem::ResolveSizeAndState( LayoutLength size, MeasureSpec measureSpec, MeasuredSize::State childMeasuredState ) @@ -405,54 +576,85 @@ bool LayoutItem::SetFrame( LayoutLength left, LayoutLength top, LayoutLength rig { bool changed = false; - DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame(%d, %d, %d, %d)\n", left.mValue, top.mValue, right.mValue, bottom.mValue ); + DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame enter(" << left << ", " << top << ", " << right << ", " << bottom << ")\n" ); - if( mImpl->mLeft != left || mImpl->mRight != right || mImpl->mTop != top || mImpl->mBottom != bottom ) + if( mImpl->mLeft != left || mImpl->mRight != right || mImpl->mTop != top || mImpl->mBottom != bottom || mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME ) ) { changed = true; + mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME ); + } - auto oldWidth = mImpl->mRight - mImpl->mLeft; - auto oldHeight = mImpl->mBottom - mImpl->mTop; - auto newWidth = right - left; - auto newHeight = bottom - top; - bool sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight); + LayoutLength oldWidth = mImpl->mRight - mImpl->mLeft; + LayoutLength oldHeight = mImpl->mBottom - mImpl->mTop; + LayoutLength newWidth = right - left; + LayoutLength newHeight = bottom - top; + bool sizeChanged = ( newWidth != oldWidth ) || ( newHeight != oldHeight ); - mImpl->mLeft = left; - mImpl->mTop = top; - mImpl->mRight = right; - mImpl->mBottom = bottom; + mImpl->mLeft = left; + mImpl->mTop = top; + mImpl->mRight = right; + mImpl->mBottom = bottom; - mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_HAS_BOUNDS ); + // Reflect up to parent control + auto owner = GetOwner(); + auto actor = Actor::DownCast( owner ); + LayoutData& layoutData = *mImpl->sLayoutData; + if( actor ) + { + if( changed || mImpl->mAnimated ) + { + layoutData.layoutPositionDataArray.push_back( + LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), mImpl->mAnimated ) ); + } - // Reflect up to parent control - auto owner = GetOwner(); - auto actor = Actor::DownCast(owner); - if( actor ) + if( mImpl->mAnimated && !layoutData.speculativeLayout ) { - if( mImpl->mAnimated ) + if( layoutData.layoutTransition.layoutTransitionType != -1 ) { - auto animation = Animation::New( 0.5f ); - animation.AnimateTo( Property( actor, Actor::Property::POSITION ), - Vector3( float(left.mValue), float(top.mValue), 0.0f ) ); - animation.AnimateTo( Property( actor, Actor::Property::SIZE ), - Vector3( right-left, bottom-top, 0.0f ) ); - animation.FinishedSignal().Connect( mSlotDelegate, &LayoutItem::OnLayoutAnimationFinished ); - animation.Play(); + LayoutItem* transitionOwner = layoutData.layoutTransition.layoutItem.Get(); + LayoutTransitionDataPtr layoutTransitionDataPtr = GetTransitionData( layoutData.layoutTransition.layoutTransitionType ); + + // Found transition owner + if( transitionOwner == this && layoutTransitionDataPtr.Get() ) + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply transition to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType ); + layoutTransitionDataPtr->CollectLayoutDataElements( actor, layoutData ); + changed = true; + } + else + { + LayoutTransitionData::CollectChildrenLayoutDataElements( actor, layoutData ); + } } else { - // @todo Collate into list of Property & Property::Value pairs. - actor.SetPosition( Vector3( float(left.mValue), float(top.mValue), 0.0f ) ); - actor.SetSize( Vector3( right-left, bottom-top, 0.0f ) ); + if( changed ) + { + LayoutTransitionDataPtr layoutTransitionDataPtr = GetTransitionData( Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE ); + if( layoutTransitionDataPtr ) // has custom default animation and normal update + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply custom default transition to (%s), transition type (%d)\n", actor.GetName().c_str(), Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE ); + layoutTransitionDataPtr->CollectLayoutDataElements( actor, layoutData ); + } + else + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply default transition to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType ); + GetDefaultTransition()->CollectLayoutDataElements( actor, layoutData ); + } + } } } + } - if( sizeChanged ) - { - SizeChange( LayoutSize( newWidth, newHeight ), LayoutSize( oldWidth, oldHeight ) ); - } + // TODO: do we need it + if( sizeChanged ) + { + SizeChange( LayoutSize( newWidth, newHeight ), LayoutSize( oldWidth, oldHeight ) ); } + + DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame exit(" << left << ", " << top << ", " << right << ", " << bottom << ")\n" ); + return changed; } @@ -462,7 +664,7 @@ void LayoutItem::OnLayoutAnimationFinished( Animation& animation ) auto actor = Actor::DownCast(owner); if( actor ) { - actor.SetSize( Vector3( mImpl->mRight-mImpl->mLeft, mImpl->mBottom-mImpl->mTop, 0.0f ) ); + actor.SetSize( Vector3( mImpl->mRight.AsInteger() - mImpl->mLeft.AsInteger(), mImpl->mBottom.AsInteger() - mImpl->mTop.AsInteger(), 0.0f ) ); } }