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<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 375.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 110.0f, 375.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 220.0f, 375.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 330.0f, 375.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
// Padding tests
int UtcDaliLayouting_HboxLayout_Padding01(void)
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 ) )
{
// If any child properties are set, must perform relayout
RequestLayout();
+ for( auto&& child : mImpl->mChildren )
+ {
+ if( child.child->GetOwner() == handle )
+ {
+ child.child->SetLayoutRequested();
+ break;
+ }
+ }
}
}
#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<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
auto desiredHeight = childOwner.GetProperty<int>( 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.
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,
// 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() );
const bool needsLayout = specChanged && ( !isSpecExactly || !matchesSpecSize );
- if( forceLayout || needsLayout)
+ if( forceLayout || needsLayout )
{
mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET );
break;
}
case MeasureSpec::Mode::AT_MOST:
+ {
+ LayoutLength tmp = specSize;
+ if( size < tmp )
+ {
+ result = size;
+ }
+ else
+ {
+ result = specSize;
+ }
+ break;
+ }
case MeasureSpec::Mode::EXACTLY:
{
result = specSize;
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();
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",
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.
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<LayoutItem*>(node->getContext());
auto childOwner = childLayout->GetOwner();
auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
}
// Measure for Yoga
- MeasureSpec ygWidthMeasureSpec = MeasureSpec( desiredWidth, static_cast<MeasureSpec::Mode>(widthMode) );
- MeasureSpec ygHeightMeasureSpec = MeasureSpec( desiredHeight, static_cast<MeasureSpec::Mode>(heightMode) );
+ MeasureSpec::Mode ygWidthMode = static_cast<MeasureSpec::Mode>(widthMode);
+ if( measureWidthMode == MeasureSpec::Mode::EXACTLY )
+ {
+ ygWidthMode = MeasureSpec::Mode::EXACTLY;
+ }
+
+ MeasureSpec::Mode ygHeightMode = static_cast<MeasureSpec::Mode>(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;