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/type-registry-helper.h>
21 #include <dali-toolkit/public-api/controls/control.h>
22 #include <dali/devel-api/object/handle-devel.h>
23 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
24 #include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
25 #include <dali-toolkit/internal/layouting/layout-transition-data-impl.h>
26 #include <dali-toolkit/internal/layouting/layout-item-data-impl.h>
28 #include <dali/devel-api/scripting/enum-helper.h>
33 #if defined(DEBUG_ENABLED)
34 Debug::Filter* gLayoutFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" );
37 const char* WIDTH_SPECIFICATION_NAME( "widthSpecification" );
38 const char* HEIGHT_SPECIFICATION_NAME( "heightSpecification" );
49 LayoutItem::LayoutItem()
50 : mImpl( new LayoutItem::Impl() ),
55 LayoutItem::~LayoutItem()
57 // An object with a unique_ptr to an opaque structure must define it's destructor in the translation unit
58 // where the opaque structure is defined. It cannot use the default method in the header file.
61 LayoutItemPtr LayoutItem::New( Handle& owner )
63 LayoutItemPtr layoutPtr = new LayoutItem();
67 void LayoutItem::Initialize( Handle& owner, const std::string& containerType )
69 mImpl->mOwner = &(owner.GetBaseObject());
70 RegisterChildProperties( containerType );
71 OnInitialize(); // Ensure direct deriving class gets initialized
74 Handle LayoutItem::GetOwner() const
76 return Handle::DownCast(BaseHandle(mImpl->mOwner));
79 void LayoutItem::Unparent()
81 // Enable directly derived types to first remove children
84 // Remove myself from parent
85 LayoutParent* parent = GetParent();
88 parent->Remove( *this );
91 // Remove parent reference
98 LayoutTransitionDataPtr LayoutItem::GetDefaultTransition()
100 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultTransition\n" );
101 if ( !mImpl->mDefaultTransitionData.Get() )
103 auto owner = GetOwner();
104 auto actor = Actor::DownCast( owner );
106 mImpl->mDefaultTransitionData = LayoutTransitionData::New();
109 map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
110 map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update
111 map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR ] = std::string(); // default animator with default duration
112 // Capture calculated position after layout, apply default linear animation
113 mImpl->mDefaultTransitionData->AddPropertyAnimator( actor, map );
117 map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
118 map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update
119 map[ Dali::Toolkit::LayoutTransitionData::AnimatorKey::ANIMATOR ] = std::string(); // default animator with default duration
120 // Capture calculated size after layout, apply default linear animation
121 mImpl->mDefaultTransitionData->AddPropertyAnimator( actor, map );
124 return mImpl->mDefaultTransitionData;
127 void LayoutItem::SetAnimateLayout( bool animateLayout )
129 auto owner = GetOwner();
130 auto actor = Actor::DownCast(owner);
132 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetAnimateLayout animateLayout(%s) owner(%s)\n", (animateLayout)?"true":"false",
133 ( ( Actor::DownCast( owner) ) ? Actor::DownCast(owner).GetName().c_str() : "Invalid Actor" ) );
135 mImpl->mAnimated = animateLayout;
137 OnAnimationStateChanged( animateLayout );
140 bool LayoutItem::IsLayoutAnimated() const
142 return mImpl->mAnimated;
145 void LayoutItem::SetTransitionData( int layoutTransitionType, Internal::LayoutTransitionDataPtr layoutTransitionDataPtr )
147 switch ( layoutTransitionType )
149 case Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD:
150 mImpl->mOnChildAddTransitionData = layoutTransitionDataPtr;
152 case Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE:
153 mImpl->mOnChildRemoveTransitionData = layoutTransitionDataPtr;
155 case Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS:
156 mImpl->mOnChildFocusTransitionData = layoutTransitionDataPtr;
158 case Dali::Toolkit::LayoutTransitionData::ON_OWNER_SET:
159 mImpl->mOnOwnerSetTransitionData = layoutTransitionDataPtr;
161 case Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE:
162 mImpl->mOnLayoutChangeTransitionData = layoutTransitionDataPtr;
169 Internal::LayoutTransitionDataPtr LayoutItem::GetTransitionData( int layoutTransitionType ) const
171 switch ( layoutTransitionType )
173 case Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD:
174 return mImpl->mOnChildAddTransitionData.Get();
175 case Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE:
176 return mImpl->mOnChildRemoveTransitionData.Get();
177 case Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS:
178 return mImpl->mOnChildFocusTransitionData.Get();
179 case Dali::Toolkit::LayoutTransitionData::ON_OWNER_SET:
180 return mImpl->mOnOwnerSetTransitionData.Get();
181 case Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE:
182 return mImpl->mOnLayoutChangeTransitionData.Get();
184 return LayoutTransitionDataPtr();
188 void LayoutItem::RegisterChildProperties( const std::string& containerType )
190 // Call on derived types
191 auto typeInfo = TypeRegistry::Get().GetTypeInfo( containerType );
194 Property::IndexContainer indices;
195 typeInfo.GetChildPropertyIndices( indices );
197 if( std::find( indices.Begin(), indices.End(), Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ) ==
200 ChildPropertyRegistration( typeInfo.GetName(), WIDTH_SPECIFICATION_NAME,
201 Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, Property::INTEGER );
203 ChildPropertyRegistration( typeInfo.GetName(), HEIGHT_SPECIFICATION_NAME,
204 Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, Property::INTEGER );
207 OnRegisterChildProperties( containerType );
211 void LayoutItem::OnRegisterChildProperties( const std::string& containerType )
216 void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec )
218 DALI_LOG_TRACE_METHOD( gLayoutFilter );
220 const bool forceLayout = mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
222 const bool specChanged =
223 ( widthMeasureSpec != mImpl->mOldWidthMeasureSpec ) ||
224 ( heightMeasureSpec != mImpl->mOldHeightMeasureSpec );
226 const bool isSpecExactly =
227 ( widthMeasureSpec.GetMode() == MeasureSpec::Mode::EXACTLY ) &&
228 ( heightMeasureSpec.GetMode() == MeasureSpec::Mode::EXACTLY );
230 const bool matchesSpecSize =
231 ( GetMeasuredWidth() == widthMeasureSpec.GetSize() ) &&
232 ( GetMeasuredHeight() == heightMeasureSpec.GetSize() );
234 const bool needsLayout = specChanged && ( !isSpecExactly || !matchesSpecSize );
236 DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::Measure("<<widthMeasureSpec<<", "<<heightMeasureSpec<<") Owner:"
237 <<Actor::DownCast(GetOwner()).GetName() <<" forceLayout="<<forceLayout
238 <<", specChanged="<<specChanged<<", isSpecExactly="<<isSpecExactly
239 <<", matchesSpecSize="<<matchesSpecSize
240 <<", needsLayout="<<needsLayout <<(forceLayout||needsLayout?" Remeasuring":" NoChange"));
242 if( forceLayout || needsLayout )
244 mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET );
246 // measure ourselves, this should set the measured dimension flag back
247 #if defined(DEBUG_ENABLED)
248 std::ostringstream o;
249 o<<widthMeasureSpec<<","<<heightMeasureSpec;
250 DALI_LOG_INFO( gLayoutFilter, Debug::General, "LayoutItem::Measure Calling %s OnMeasure( %s )\n", Actor::DownCast(GetOwner()).GetName().c_str(), o.str().c_str());
252 OnMeasure( widthMeasureSpec, heightMeasureSpec );
253 mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT );
255 // flag not set, setMeasuredDimension() was not invoked, we raise an exception to warn the developer
256 DALI_ASSERT_ALWAYS( mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET ) &&
257 "Layout's OnMeasure() Measured dimension flag not set" );
258 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED );
261 mImpl->mOldWidthMeasureSpec = widthMeasureSpec;
262 mImpl->mOldHeightMeasureSpec = heightMeasureSpec;
265 void LayoutItem::Layout( LayoutLength l, LayoutLength t, LayoutLength r, LayoutLength b )
267 DALI_LOG_TRACE_METHOD( gLayoutFilter );
269 if( mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT ) )
271 OnMeasure( mImpl->mOldWidthMeasureSpec, mImpl->mOldHeightMeasureSpec );
272 mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT );
275 LayoutData& layoutData = *mImpl->sLayoutData;
276 size_t size = layoutData.childrenPropertyAnimators.size();
278 bool changed = SetFrame( l, t, r, b );
280 if( changed || mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED ) )
283 OnLayout( changed, l, t, r, b );
284 mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED );
287 if ( size != layoutData.childrenPropertyAnimators.size() )
289 layoutData.childrenPropertyAnimators.resize( size );
292 mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
293 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_IS_LAID_OUT );
296 LayoutLength LayoutItem::GetMinimumWidth() const
298 return mImpl->mMinimumSize.GetWidth();
301 LayoutLength LayoutItem::GetMinimumHeight() const
303 return mImpl->mMinimumSize.GetHeight();
306 void LayoutItem::SetMinimumWidth( LayoutLength minimumWidth )
308 mImpl->mMinimumSize.SetWidth( minimumWidth );
312 void LayoutItem::SetMinimumHeight( LayoutLength minimumHeight )
314 mImpl->mMinimumSize.SetHeight( minimumHeight );
318 Extents LayoutItem::GetPadding() const
320 Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
323 Extents padding = control.GetProperty<Extents>( Toolkit::Control::Property::PADDING );
325 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::Padding for %s : (%d,%d,%d,%d) \n",
326 control.GetName().c_str(),
327 padding.start, padding.end, padding.top, padding.bottom
337 Extents LayoutItem::GetMargin() const
339 Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
342 return control.GetProperty<Extents>( Toolkit::Control::Property::MARGIN );
350 LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureSpec )
352 LayoutLength result = size;
353 auto specMode = measureSpec.GetMode();
354 auto specSize = measureSpec.GetSize();
356 DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultSize size:" << size << "MeasureSpec(" << measureSpec << ") \n" );
360 case MeasureSpec::Mode::UNSPECIFIED:
365 case MeasureSpec::Mode::AT_MOST:
367 // Ensure the default size does not exceed the spec size unless the default size is 0.
368 // Another container could provide a default size of 0.
370 // Do not set size to 0, use specSize in this case as could be a legacy container
371 if( ( size < specSize ) && ( size > LayoutLength( 0 ) ) )
381 case MeasureSpec::Mode::EXACTLY:
387 DALI_LOG_STREAM( gLayoutFilter, Debug::General, "LayoutItem::GetDefaultSize setting default size:" << result << "\n" );
391 void LayoutItem::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec)
393 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::OnMeasure\n");
395 // GetDefaultSize will limit the MeasureSpec to the suggested minimumWidth and minimumHeight
396 auto minimumWidth = GetSuggestedMinimumWidth();
397 auto minimumHeight = GetSuggestedMinimumHeight();
398 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::OnMeasure minimumWidth(%f) minimumHeight(%f)\n",
399 minimumWidth.AsInteger(), minimumHeight.AsInteger() );
401 SetMeasuredDimensions( GetDefaultSize( minimumWidth, widthMeasureSpec ),
402 GetDefaultSize( minimumHeight, heightMeasureSpec ) );
405 void LayoutItem::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
409 void LayoutItem::SetParent( LayoutParent* parent )
411 mImpl->mLayoutParent = parent;
412 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME );
415 LayoutParent* LayoutItem::GetParent()
417 return mImpl->mLayoutParent;
420 void LayoutItem::RequestLayout()
422 Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
425 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s)\n",
426 control.GetName().c_str() );
428 // @todo Enforce failure if called in Measure/Layout passes.
429 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
430 Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
431 layoutController.RequestLayout( Toolkit::LayoutItem( this ) );
434 void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutAnimationType )
436 Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
439 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s) layoutTranstionType(%d)\n",
440 control.GetName().c_str(), (int)layoutAnimationType );
442 // @todo Enforce failure if called in Measure/Layout passes.
443 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
444 Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
445 layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType );
448 void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutAnimationType, Actor gainedChild, Actor lostChild )
450 Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
453 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s) layoutTranstionType(%d)\n",
454 control.GetName().c_str(), (int)layoutAnimationType );
456 // @todo Enforce failure if called in Measure/Layout passes.
457 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
458 Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
459 layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType, gainedChild, lostChild );
462 bool LayoutItem::IsLayoutRequested() const
464 return mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
467 void LayoutItem::SetLayoutRequested()
469 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
472 bool LayoutItem::IsResizePolicyRequired() const
474 return mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
477 void LayoutItem::SetResizePolicyRequired( bool resizePolicyRequired )
479 if( resizePolicyRequired )
481 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
485 mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
489 void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight )
492 DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetMeasuredDimensions width(" << measuredWidth.GetSize() << ") height(" << measuredHeight.GetSize() << ") Control:" <<
493 ( ( Actor::DownCast( GetOwner()) ) ? Actor::DownCast(GetOwner()).GetName().c_str() : "Invalid Actor" ) << "\n" );
495 mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET );
496 mImpl->mMeasuredWidth = measuredWidth;
497 mImpl->mMeasuredHeight = measuredHeight;
500 LayoutLength LayoutItem::GetMeasuredWidth() const
502 // Get the size portion of the measured width
503 return mImpl->mMeasuredWidth.GetSize();
506 LayoutLength LayoutItem::GetMeasuredHeight() const
508 return mImpl->mMeasuredHeight.GetSize();
511 MeasuredSize LayoutItem::GetMeasuredWidthAndState() const
513 return mImpl->mMeasuredWidth;
516 MeasuredSize LayoutItem::GetMeasuredHeightAndState() const
518 return mImpl->mMeasuredHeight;
521 LayoutLength LayoutItem::GetSuggestedMinimumWidth() const
523 auto owner = GetOwner();
524 auto actor = Actor::DownCast(owner);
525 auto naturalSize = actor ? actor.GetNaturalSize() : Vector3::ZERO;
526 LayoutLength layoutMinimumWidth = GetMinimumWidth();
528 // Set minimum size takes precedence over natural size.
529 LayoutLength result = std::max( layoutMinimumWidth, LayoutLength( naturalSize.width ) );
531 if( actor.GetChildCount() == 0 ) // If not a container
533 LayoutLength targetWidth = GetTargetWidth();
534 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetSuggestedMinimumWidth targetWidth(%f)\n", targetWidth.AsInteger() );
535 result = (result > 0 && (targetWidth < 1 ) ) ? result : targetWidth; // Use size set if no mininum width and control has no natural size.
538 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetSuggestedMinimumWidth control(%s) naturalWidth(%f) minimumSize.width(%f) targetWidth(%f) result(%f)\n",
539 actor.GetName().c_str(), LayoutLength( naturalSize.width ).AsInteger(), layoutMinimumWidth.AsInteger(), actor.GetTargetSize().width, result.AsInteger() );
543 LayoutLength LayoutItem::GetSuggestedMinimumHeight() const
545 auto owner = GetOwner();
546 auto actor = Actor::DownCast(owner);
547 auto naturalSize = actor ? actor.GetNaturalSize() : Vector3::ZERO;
548 LayoutLength layoutMinimumHeight = GetMinimumHeight();
550 // Set minimum size takes precedence over natural size.
551 LayoutLength result = std::max( layoutMinimumHeight, LayoutLength( naturalSize.height ) );
553 if( actor.GetChildCount() == 0 ) // If not a container
555 LayoutLength targetHeight = GetTargetHeight();
556 result = (result > 0 && (targetHeight < 1 ) )?result : targetHeight; // Use size set if no mininum width and control has no natural size.
559 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetSuggestedMinimumHeight control(%s) naturalHeight(%f) minimumHeight(%f) targetHeight(%f) result(%f)\n",
560 actor.GetName().c_str(), naturalSize.height, layoutMinimumHeight.AsInteger(), actor.GetTargetSize().height, result.AsInteger() );
564 MeasuredSize LayoutItem::ResolveSizeAndState( LayoutLength size, MeasureSpec measureSpec, MeasuredSize::State childMeasuredState )
566 auto specMode = measureSpec.GetMode();
567 LayoutLength specSize = measureSpec.GetSize();
572 case MeasureSpec::Mode::AT_MOST:
576 result = MeasuredSize( specSize, MeasuredSize::MEASURED_SIZE_TOO_SMALL );
580 result.SetSize( size );
585 case MeasureSpec::Mode::EXACTLY:
587 result.SetSize( specSize );
591 case MeasureSpec::Mode::UNSPECIFIED:
594 result.SetSize( size );
599 result.SetState( childMeasuredState );
604 bool LayoutItem::SetFrame( LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
606 bool changed = false;
608 DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame enter(" << left << ", " << top << ", " << right << ", " << bottom << ")\n" );
610 if( mImpl->mLeft != left || mImpl->mRight != right || mImpl->mTop != top || mImpl->mBottom != bottom || mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME ) )
613 mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME );
616 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame %s changed size(%s)\n",
617 Actor::DownCast( GetOwner() ).GetName().c_str(), (changed)?"yes":"no" );
619 LayoutLength oldWidth = mImpl->mRight - mImpl->mLeft;
620 LayoutLength oldHeight = mImpl->mBottom - mImpl->mTop;
621 LayoutLength newWidth = right - left;
622 LayoutLength newHeight = bottom - top;
623 bool sizeChanged = ( newWidth != oldWidth ) || ( newHeight != oldHeight );
627 mImpl->mRight = right;
628 mImpl->mBottom = bottom;
630 // Reflect up to parent control
631 auto owner = GetOwner();
632 auto actor = Actor::DownCast( owner );
633 LayoutData& layoutData = *mImpl->sLayoutData;
636 if( mImpl->mAnimated && !layoutData.speculativeLayout )
638 LayoutItem* transitionOwner = layoutData.layoutTransition.layoutItem.Get();
639 LayoutTransitionDataPtr layoutTransitionDataPtr = GetTransitionData( layoutData.layoutTransition.layoutTransitionType );
641 // Found transition owner
642 if( transitionOwner == this && layoutTransitionDataPtr.Get() )
644 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply transition to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType );
645 layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) );
646 layoutTransitionDataPtr->ConvertToLayoutDataElements( actor, layoutData );
653 layoutTransitionDataPtr = GetTransitionData( Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE );
654 if ( layoutTransitionDataPtr )
656 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 );
657 layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) );
658 layoutTransitionDataPtr->ConvertToLayoutDataElements( actor, layoutData );
662 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply default transition to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType );
663 layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) );
664 GetDefaultTransition()->ConvertToLayoutDataElements( actor, layoutData );
669 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply children animators to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType );
670 layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) );
671 LayoutTransitionData::ConvertChildrenAnimatorsToLayoutDataElements( actor, layoutData );
679 layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), false ) );
684 // TODO: do we need it
687 SizeChange( LayoutSize( newWidth, newHeight ), LayoutSize( oldWidth, oldHeight ) );
690 DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame exit(" << left << ", " << top << ", " << right << ", " << bottom << ")\n" );
695 LayoutLength LayoutItem::GetTargetWidth() const
697 return mImpl->mTargetWidth;
700 LayoutLength LayoutItem::GetTargetHeight() const
702 return mImpl->mTargetHeight;
705 void LayoutItem::SetTargetWidth( LayoutLength width )
707 mImpl->mTargetWidth = width;
710 void LayoutItem::SetTargetHeight( LayoutLength height )
712 mImpl->mTargetHeight = height;
715 void LayoutItem::OnLayoutAnimationFinished( Animation& animation )
717 auto owner = GetOwner();
718 auto actor = Actor::DownCast(owner);
721 actor.SetSize( Vector3( mImpl->mRight.AsInteger() - mImpl->mLeft.AsInteger(), mImpl->mBottom.AsInteger() - mImpl->mTop.AsInteger(), 0.0f ) );
725 void LayoutItem::SizeChange( LayoutSize newSize, LayoutSize oldSize)
727 OnSizeChanged( newSize, oldSize );
731 void LayoutItem::OnSizeChanged( LayoutSize newSize, LayoutSize oldSize )
735 void LayoutItem::OnInitialize()
740 } // namespace Internal
741 } // namespace Toolkit