From: Anton Obzhirov Date: Mon, 11 Jun 2018 18:04:29 +0000 (+0100) Subject: Fix WIDTH_SPECIFICATION & HEIGHT_SPECIFICATION bug. X-Git-Tag: dali_1.3.29~14 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=8e98f1407744af67cc5b5f37e979c2496468c50c Fix WIDTH_SPECIFICATION & HEIGHT_SPECIFICATION bug. Change-Id: I10b5faacc51491fdd2cf3ca6c9181a526c0f271c --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp index 49bb007..6abc0c7 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp @@ -389,6 +389,54 @@ int UtcDaliLayouting_HboxLayout04(void) END_TEST; } +int UtcDaliLayouting_HboxLayout05(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_HboxLayout05 - Set children size explicitly via width & height specification"); + + Stage stage = Stage::GetCurrent(); + auto hbox = Control::New(); + auto hboxLayout = HboxLayout::New(); + hboxLayout.SetCellPadding( LayoutSize( 10, 0 ) ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetName( "HBox"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 40, 40 ) ); + controls.push_back( CreateLeafControl( 60, 40 ) ); + controls.push_back( CreateLeafControl( 80, 40 ) ); + controls.push_back( CreateLeafControl( 100, 40 ) ); + + for( auto&& iter : controls ) + { + hbox.Add( iter ); + iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 100 ); + iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 50 ); + } + + hbox.SetParentOrigin( ParentOrigin::CENTER ); + hbox.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( hbox ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + // hbox centers elements vertically, it fills test harness stage, which is 480x800. + // hbox left justifies elements + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 375.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 110.0f, 375.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 220.0f, 375.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::POSITION ), Vector3( 330.0f, 375.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + // Padding tests int UtcDaliLayouting_HboxLayout_Padding01(void) diff --git a/dali-toolkit/devel-api/layouting/layout-group-impl.cpp b/dali-toolkit/devel-api/layouting/layout-group-impl.cpp index 9df05c6..10bfe2d 100644 --- a/dali-toolkit/devel-api/layouting/layout-group-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-group-impl.cpp @@ -182,7 +182,7 @@ void LayoutGroup::DoRegisterChildProperties( const std::string& containerType ) void LayoutGroup::OnSetChildProperties( Handle& handle, Property::Index index, Property::Value value ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnSetChildProperties"); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnSetChildProperties\n"); if ( ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= CHILD_PROPERTY_REGISTRATION_MAX_INDEX ) ) @@ -191,6 +191,14 @@ void LayoutGroup::OnSetChildProperties( Handle& handle, Property::Index index, P { // If any child properties are set, must perform relayout RequestLayout(); + for( auto&& child : mImpl->mChildren ) + { + if( child.child->GetOwner() == handle ) + { + child.child->SetLayoutRequested(); + break; + } + } } } @@ -226,36 +234,14 @@ void LayoutGroup::MeasureChild( LayoutItemPtr child, #if defined( DEBUG_ENABLED ) if ( control ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChildWithMargins naturalSizewidth(%f)\n", control.GetNaturalSize().width ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChild natural size(%f, %f)\n", control.GetNaturalSize().width, control.GetNaturalSize().height ); } #endif // Get last stored width and height specifications for the child auto desiredWidth = childOwner.GetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ); auto desiredHeight = childOwner.GetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION ); - - // The size of the control could have changed due to padding being altered, the XXX_SPECIFICATIONs will not have been updated. - // So GetNaturalSize is called, if the control's natural size includes padding then th size will be updated. - if ( control ) - { - auto desiredSize = control.GetNaturalSize(); // Get's child control's size which could include new padding values. - - // Check if WIDTH_SPECIFICATION was a size value, if so then get update to child controls's width. - if ( desiredWidth > 0 ) - { - desiredWidth = desiredSize.width; - childOwner.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, LayoutLength::IntType( desiredWidth ) ); - } - - // Check if HEIGHT_SPECIFICATION was a size value, if so then get update to child controls's height. - if ( desiredHeight > 0) - { - desiredHeight = desiredSize.height; - childOwner.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, LayoutLength::IntType( desiredHeight ) ); - } - } - - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChild desiredWidth(%d)\n", desiredWidth ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChild desiredWidth(%d) desiredHeight(%d)\n", desiredWidth, desiredHeight ); auto padding = GetPadding(); // Padding of this layout's owner, not of the child being measured. @@ -279,7 +265,6 @@ void LayoutGroup::MeasureChildWithMargins( LayoutItemPtr child, auto padding = GetPadding(); // Padding of this layout's owner, not of the child being measured. - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChildWithMargins desiredWidth(%d)\n", desiredWidth ); MeasureSpec childWidthMeasureSpec = GetChildMeasureSpec( parentWidthMeasureSpec, @@ -451,15 +436,13 @@ void LayoutGroup::ChildAddedToOwner( Actor child ) // If the child doesn't already have a layout, then create a LayoutItem for it. childLayout = LayoutItem::New( control ); childLayout->SetAnimateLayout( IsLayoutAnimated() ); // @todo this essentially forces animation inheritance. Bad? - +#if defined(DEBUG_ENABLED) auto desiredSize = control.GetNaturalSize(); DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner desiredSize(%f,%f) (naturalSize)\n", desiredSize.width, desiredSize.height ); - +#endif childControlDataImpl.SetLayout( *childLayout.Get() ); - // Default layout data for this object - child.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, LayoutLength::IntType( desiredSize.width ) ); - child.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, LayoutLength::IntType( desiredSize.height ) ); + // Default layout data will be generated by Add(). } Add( *childLayout.Get() ); diff --git a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp index be5b0ed..217ffa6 100644 --- a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp @@ -140,7 +140,7 @@ void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasur const bool needsLayout = specChanged && ( !isSpecExactly || !matchesSpecSize ); - if( forceLayout || needsLayout) + if( forceLayout || needsLayout ) { mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET ); @@ -246,6 +246,18 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS break; } case MeasureSpec::Mode::AT_MOST: + { + LayoutLength tmp = specSize; + if( size < tmp ) + { + result = size; + } + else + { + result = specSize; + } + break; + } case MeasureSpec::Mode::EXACTLY: { result = specSize; @@ -272,6 +284,11 @@ LayoutParent* LayoutItem::GetParent() void LayoutItem::RequestLayout() { + Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner ); + if ( control ) + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout %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(); @@ -283,6 +300,11 @@ bool LayoutItem::IsLayoutRequested() const return mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); } +void LayoutItem::SetLayoutRequested() +{ + return mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); +} + void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight ) { DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutBase::SetMeasuredDimensions width(%d) height(%d) \n", diff --git a/dali-toolkit/devel-api/layouting/layout-item-impl.h b/dali-toolkit/devel-api/layouting/layout-item-impl.h index e91e7f9..e59ca96 100644 --- a/dali-toolkit/devel-api/layouting/layout-item-impl.h +++ b/dali-toolkit/devel-api/layouting/layout-item-impl.h @@ -187,6 +187,11 @@ public: bool IsLayoutRequested() const; /** + * @brief Set layout requested flag (mark the layout dirty). + */ + void SetLayoutRequested(); + + /** * @brief Get the measured width (without any measurement flags). * * This method should be used only during measurement and layout calculations. diff --git a/dali-toolkit/internal/layouting/flex-layout-impl.cpp b/dali-toolkit/internal/layouting/flex-layout-impl.cpp index ebbf330..7bba696 100644 --- a/dali-toolkit/internal/layouting/flex-layout-impl.cpp +++ b/dali-toolkit/internal/layouting/flex-layout-impl.cpp @@ -286,6 +286,8 @@ YGSize FlexLayout::OnChildMeasure( YGNodeRef node, YGMeasureMode widthMode, float innerHeight, YGMeasureMode heightMode ) { + // TODO: this function should try to get use of LayoutGroup::GetChildMeasureSpec + // or LayoutGroup::MeasureChild somehow since it is fixed now LayoutItem* childLayout = static_cast(node->getContext()); auto childOwner = childLayout->GetOwner(); auto desiredWidth = childOwner.GetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ); @@ -348,8 +350,20 @@ YGSize FlexLayout::OnChildMeasure( YGNodeRef node, } // Measure for Yoga - MeasureSpec ygWidthMeasureSpec = MeasureSpec( desiredWidth, static_cast(widthMode) ); - MeasureSpec ygHeightMeasureSpec = MeasureSpec( desiredHeight, static_cast(heightMode) ); + MeasureSpec::Mode ygWidthMode = static_cast(widthMode); + if( measureWidthMode == MeasureSpec::Mode::EXACTLY ) + { + ygWidthMode = MeasureSpec::Mode::EXACTLY; + } + + MeasureSpec::Mode ygHeightMode = static_cast(heightMode); + if( measureHeightMode == MeasureSpec::Mode::EXACTLY ) + { + ygHeightMode = MeasureSpec::Mode::EXACTLY; + } + + MeasureSpec ygWidthMeasureSpec = MeasureSpec( desiredWidth, ygWidthMode ); + MeasureSpec ygHeightMeasureSpec = MeasureSpec( desiredHeight, ygHeightMode ); #if defined(DEBUG_ENABLED) auto actor = Actor::DownCast(childOwner); std::ostringstream oss;