END_TEST;
}
+int UtcDaliLayouting_HboxLayout_Weight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( " UtcDaliLayouting_HboxLayout_Weight - Test LinearLayout weight horizontally" );
+
+ Stage stage = Stage::GetCurrent();
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ 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 ) );
+
+ // Set weight for each leaf to use quarter of available space
+ // 480 * 0.25, 480 * 0.25, 480 * 0.25, 480 * 0.25,
+ // width spec has to be set to 0 so not to consume any extra space.
+ for( auto&& iter : controls )
+ {
+ iter.SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.25f );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 0 );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ hbox.Add( iter );
+ }
+
+ hbox.SetParentOrigin( ParentOrigin::CENTER );
+ hbox.SetAnchorPoint( AnchorPoint::CENTER );
+ stage.Add( hbox );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 120.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 240.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 360.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Set weight for 3, 4 leafs to use all remaining available space after 1, 2 content sized leafs.
+ // 40, 60, (480 - 40 - 60) * 0.5, (480 - 40 - 60) * 0.5
+ controls[0].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[0].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[1].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[1].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[2].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.5f );
+ controls[3].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.5f );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 290.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 190.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 190.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Add intrinsic width for 3rd leaf so now we should get
+ // 40, 60, (480 - 40 - 60 - 80) * 0.5 + 80, (480 - 40 - 60 - 80) * 0.5
+ controls[2].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 80 );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 330.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 230.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 150.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ controls[0].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 0 );
+ controls[0].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.25f );
+ controls[1].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 0 );
+ controls[1].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.5f );
+ controls[2].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 0 );
+ controls[2].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.25f );
+ controls[3].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 40 );
+ controls[3].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 110.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 330.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 440.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 110.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 220.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 110.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // WRAP_CONTENT doesn't affect weight
+ controls[0].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[0].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[1].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[1].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[2].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[2].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[3].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[3].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 1 );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 180.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 300.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // MATCH_PARENT doesn't affect weight
+ for( auto&& iter : controls )
+ {
+ iter.SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.25f );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ }
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 120.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 240.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 360.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ const Extents CONTROL_MARGIN = Extents( 10, 10, 0, 0 );
+ for( auto&& iter : controls )
+ {
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ iter.SetProperty( Toolkit::Control::Property::MARGIN, CONTROL_MARGIN );
+ }
+
+ controls[0].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[1].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[2].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[3].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 1 );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 10.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 70.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 150.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 250.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 220.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliLayouting_VboxLayout_Weight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( " UtcDaliLayouting_VboxLayout_Weight - Test LinearLayout weight vertically" );
+
+ Stage stage = Stage::GetCurrent();
+ auto vbox = Control::New();
+ auto vboxLayout = LinearLayout::New();
+ vboxLayout.SetOrientation( Dali::Toolkit::LinearLayout::Orientation::VERTICAL );
+ DevelControl::SetLayout( vbox, vboxLayout );
+ vbox.SetName( "VBox" );
+
+ std::vector<Control> controls;
+ controls.push_back( CreateLeafControl( 40, 40 ) );
+ controls.push_back( CreateLeafControl( 60, 60 ) );
+ controls.push_back( CreateLeafControl( 80, 80 ) );
+ controls.push_back( CreateLeafControl( 100, 100 ) );
+
+ // Set weight for each leaf to use quarter of available space
+ // 800 * 0.25, 800 * 0.25, 800 * 0.25, 800 * 0.25,
+ // width spec has to be set to 0 so not to consume any extra space.
+ for( auto&& iter : controls )
+ {
+ iter.SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.25f );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 0 );
+ vbox.Add( iter );
+ }
+
+ vbox.SetParentOrigin( ParentOrigin::CENTER );
+ vbox.SetAnchorPoint( AnchorPoint::CENTER );
+ stage.Add( vbox );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 600.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Set weight for 3, 4 leafs to use all remaining available space after 1, 2 content sized leafs.
+ // 40, 60, (800 - 40 - 60) * 0.5, (800 - 40 - 60) * 0.5
+ controls[0].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[0].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[1].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[1].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[2].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.5f );
+ controls[3].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.5f );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 450.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Add intrinsic width for 3rd leaf so now we should get
+ // 40, 60, (800 - 40 - 60 - 100) * 0.5 + 100, (800 - 40 - 60 - 100) * 0.5
+ controls[2].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 100 );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 500.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ controls[0].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 0 );
+ controls[0].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.25f );
+ controls[1].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 0 );
+ controls[1].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.5f );
+ controls[2].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 0 );
+ controls[2].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.25f );
+ controls[3].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 100 );
+ controls[3].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 175.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 525.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 700.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 175.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 175.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // WRAP_CONTENT doesn't affect weight
+ controls[0].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[0].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[1].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[1].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[2].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[2].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[3].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ controls[3].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 1 );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 180.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 620.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // MATCH_PARENT doesn't affect weight
+ for( auto&& iter : controls )
+ {
+ iter.SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.25f );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ }
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 600.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ const Extents CONTROL_MARGIN = Extents( 0, 0, 10, 10 );
+ for( auto&& iter : controls )
+ {
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ iter.SetProperty( Toolkit::Control::Property::MARGIN, CONTROL_MARGIN );
+ }
+
+ controls[0].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[1].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[2].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0 );
+ controls[3].SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 1 );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 10.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 70.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 150.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 250.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 540.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliLayouting_NestedLinearLayout_Weight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliLayouting_NestedLinearLayout_Weight - test weighted children with wrapped parent");
+
+ Stage stage = Stage::GetCurrent();
+ auto rootControl = Control::New();
+ rootControl.SetName( "AbsoluteLayout");
+ auto rootLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, rootLayout );
+ rootControl.SetAnchorPoint( AnchorPoint::CENTER );
+ rootControl.SetParentOrigin( ParentOrigin::CENTER );
+ stage.Add( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ DevelControl::SetLayout( hbox, hboxLayout );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+
+ std::vector< Control > controls;
+ controls.push_back( CreateLeafControl( 40, 40 ) );
+ controls.push_back( CreateLeafControl( 60, 60 ) );
+
+ // set equal share of wrapped content width (40 + 60 = 100) for both children 100 * 0.5, 100 * 0.5
+ for( auto&& iter : controls )
+ {
+ iter.SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.5f );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 0 );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ hbox.Add( iter );
+ }
+
+ hbox.SetParentOrigin( ParentOrigin::CENTER );
+ hbox.SetAnchorPoint( AnchorPoint::CENTER );
+ rootControl.Add( hbox );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 10.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 50.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 50.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 50.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ hboxLayout.SetOrientation(Dali::Toolkit::LinearLayout::Orientation::VERTICAL);
+
+ // set equal share of wrapped content height (40 + 60 = 100) for both children 100 * 0.5, 100 * 0.5
+ for( auto&& iter : controls )
+ {
+ iter.SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.5f );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ iter.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 0 );
+ }
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 50.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+
namespace
{
const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/broken.png";
#include <dali/integration-api/debug.h>
#include <dali/public-api/common/extents.h>
#include <dali/public-api/actors/actor.h>
+#include <dali/devel-api/object/handle-devel.h>
//INTERNAL INCLUDES
#include <dali-toolkit/devel-api/layouting/layout-item.h>
{
}
+void LinearLayout::DoRegisterChildProperties( const std::string& containerType )
+{
+ auto typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( containerType );
+ if( typeInfo )
+ {
+ Property::IndexContainer indices;
+ typeInfo.GetChildPropertyIndices( indices );
+
+ if( std::find( indices.Begin(), indices.End(), Toolkit::LinearLayout::ChildProperty::WEIGHT ) ==
+ indices.End() )
+ {
+ ChildPropertyRegistration( typeInfo.GetName(), "weight", Toolkit::LinearLayout::ChildProperty::WEIGHT, Property::FLOAT );
+ }
+ }
+}
+
+void LinearLayout::OnChildAdd( LayoutItem& child )
+{
+ auto owner = child.GetOwner();
+ if( !DevelHandle::DoesCustomPropertyExist( owner, Toolkit::LinearLayout::ChildProperty::WEIGHT ) )
+ {
+ owner.SetProperty( Toolkit::LinearLayout::ChildProperty::WEIGHT, 0.0f );
+ }
+}
+
void LinearLayout::SetCellPadding( LayoutSize size )
{
if ( mCellPadding != size )
{
auto widthMode = widthMeasureSpec.GetMode();
auto heightMode = heightMeasureSpec.GetMode();
- bool isExactly = (widthMode == MeasureSpec::Mode::EXACTLY);
+ bool isExactly = ( widthMode == MeasureSpec::Mode::EXACTLY );
bool matchHeight = false;
bool allFillParent = true;
LayoutLength maxHeight = 0;
LayoutLength alternativeMaxHeight = 0;
+ LayoutLength weightedMaxHeight = 0;
+ float totalWeight = 0;
+ int usedExcessSpace = 0;
struct
{
MeasuredSize::State widthState;
mTotalLength = 0;
// measure children, and determine if further resolution is required
- for( unsigned int i=0; i<GetChildCount(); ++i )
+
+ // 1st phase:
+ // We cycle through all children and measure children with weight 0 (non weighted children) according to their specs
+ // to accumulate total used space in mTotalLength based on measured sizes and margins.
+ // Weighted children are not measured at this phase.
+ // Available space for weighted children will be calculated in the phase 2 based on mTotalLength value.
+ for( unsigned int i = 0; i < GetChildCount(); ++i )
{
auto childLayout = GetChildAt( i );
if( childLayout )
{
auto childOwner = childLayout->GetOwner();
auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
-
- MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
- auto childWidth = childLayout->GetMeasuredWidth();
+ auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+ auto childWeight = childOwner.GetProperty<float>( Toolkit::LinearLayout::ChildProperty::WEIGHT );
auto childMargin = childLayout->GetMargin();
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LinearLayout::OnMeasure childWidth(%d)\n", MeasureSpec::IntType( childWidth ) );
-
- auto length = childWidth + LayoutLength::IntType(childMargin.start + childMargin.end);
-
- auto cellPadding = i<GetChildCount()-1 ? mCellPadding.width: 0;
+ totalWeight += childWeight;
- if( isExactly )
+ const bool useExcessSpace = desiredWidth == 0 && childWeight > 0;
+ if( isExactly && useExcessSpace )
{
- mTotalLength += length;
+ mTotalLength += childMargin.start + childMargin.end;
}
else
{
- auto totalLength = mTotalLength;
- mTotalLength = std::max( totalLength, totalLength + length + cellPadding );
+ LayoutLength childWidth = 0;
+ if( useExcessSpace )
+ {
+ // The widthMode is either UNSPECIFIED or AT_MOST, and
+ // this child is only laid out using excess space. Measure
+ // using WRAP_CONTENT so that we can find out the view's
+ // optimal width.
+ auto padding = GetPadding();
+ const MeasureSpec childWidthMeasureSpec = GetChildMeasureSpec( widthMeasureSpec, padding.start + padding.end, Toolkit::ChildLayoutData::WRAP_CONTENT );
+ const MeasureSpec childHeightMeasureSpec = GetChildMeasureSpec( heightMeasureSpec, padding.top + padding.bottom, desiredHeight );
+ childLayout->Measure( childWidthMeasureSpec, childHeightMeasureSpec );
+ childWidth = childLayout->GetMeasuredWidth();
+ usedExcessSpace += childWidth;
+ }
+ else
+ {
+ MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
+ childWidth = childLayout->GetMeasuredWidth();
+ }
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LinearLayout::OnMeasure childWidth(%d)\n", MeasureSpec::IntType( childWidth ) );
+ auto length = childWidth + LayoutLength::IntType( childMargin.start + childMargin.end );
+ auto cellPadding = i < GetChildCount() - 1 ? mCellPadding.width : 0;
+ if( isExactly )
+ {
+ mTotalLength += length;
+ }
+ else
+ {
+ auto totalLength = mTotalLength;
+ mTotalLength = std::max( totalLength, totalLength + length + cellPadding );
+ }
}
bool matchHeightLocally = false;
maxHeight = std::max( maxHeight, childHeight );
allFillParent = ( allFillParent && desiredHeight == Toolkit::ChildLayoutData::MATCH_PARENT );
- alternativeMaxHeight = std::max( alternativeMaxHeight, matchHeightLocally ? marginHeight : childHeight );
+ if( childWeight > 0 )
+ {
+ /*
+ * Heights of weighted Views are bogus if we end up
+ * remeasuring, so keep them separate.
+ */
+ weightedMaxHeight = std::max( weightedMaxHeight, matchHeightLocally ? marginHeight : childHeight );
+ }
+ else
+ {
+ alternativeMaxHeight = std::max( alternativeMaxHeight, matchHeightLocally ? marginHeight : childHeight );
+ }
}
}
MeasuredSize widthSizeAndState = ResolveSizeAndState( widthSize, widthMeasureSpec, MeasuredSize::State::MEASURED_SIZE_OK);
widthSize = widthSizeAndState.GetSize();
+ // Expand children with weight to take up available space
+ // 2nd phase:
+ // We cycle through weighted children now (children with weight > 0).
+ // The children are measured with exact size equal to their share of the available space based on their weights.
+ // mTotalLength is updated to include weighted children measured sizes.
+ int remainingExcess = widthSize - mTotalLength + usedExcessSpace;
+ if( remainingExcess != 0 && totalWeight > 0 )
+ {
+ float remainingWeightSum = totalWeight;
+ maxHeight = 0;
+ mTotalLength = 0;
+
+ for( unsigned int i = 0; i < GetChildCount(); ++i )
+ {
+ auto childLayout = GetChildAt( i );
+ auto childOwner = childLayout->GetOwner();
+ auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+ auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+ auto childWeight = childOwner.GetProperty<float>( Toolkit::LinearLayout::ChildProperty::WEIGHT );
+ auto childMargin = childLayout->GetMargin();
+
+ LayoutLength childWidth = 0;
+ if( childWeight > 0 )
+ {
+ int share = static_cast<int>( childWeight * remainingExcess / remainingWeightSum );
+ remainingExcess -= share;
+ remainingWeightSum -= childWeight;
+
+ // Always lay out weighted elements with intrinsic size regardless of the parent spec.
+ // for consistency between specs.
+ if( desiredWidth == 0 )
+ {
+ // This child needs to be laid out from scratch using
+ // only its share of excess space.
+ childWidth = share;
+ }
+ else
+ {
+ // This child had some intrinsic width to which we
+ // need to add its share of excess space.
+ childWidth = childLayout->GetMeasuredWidth() + share;
+ }
+
+ const MeasureSpec childWidthMeasureSpec = MeasureSpec( childWidth, MeasureSpec::Mode::EXACTLY );
+ const MeasureSpec childHeightMeasureSpec = GetChildMeasureSpec( heightMeasureSpec, padding.top + padding.bottom, desiredHeight );
+ childLayout->Measure( childWidthMeasureSpec, childHeightMeasureSpec );
+
+ // Child may now not fit in horizontal dimension.
+ if( childLayout->GetMeasuredWidthAndState().GetState() == MeasuredSize::State::MEASURED_SIZE_TOO_SMALL )
+ {
+ childState.widthState = MeasuredSize::State::MEASURED_SIZE_TOO_SMALL;
+ }
+ }
+
+ auto length = childLayout->GetMeasuredWidth() + LayoutLength::IntType( childMargin.start + childMargin.end );
+ auto cellPadding = i < GetChildCount() - 1 ? mCellPadding.width : 0;
+ if( isExactly )
+ {
+ mTotalLength += length;
+ }
+ else
+ {
+ auto totalLength = mTotalLength;
+ mTotalLength = std::max( totalLength, totalLength + length + cellPadding );
+ }
+
+ bool matchHeightLocally = heightMode != MeasureSpec::Mode::EXACTLY && desiredHeight == Toolkit::ChildLayoutData::MATCH_PARENT;
+ auto marginHeight = LayoutLength( childMargin.top + childMargin.bottom );
+ auto childHeight = childLayout->GetMeasuredHeight() + marginHeight;
+
+ maxHeight = std::max( maxHeight, childHeight );
+ alternativeMaxHeight = std::max( alternativeMaxHeight, matchHeightLocally ? marginHeight : childHeight );
+ allFillParent = (allFillParent && desiredHeight == Toolkit::ChildLayoutData::MATCH_PARENT);
+
+ mTotalLength += padding.start + padding.end;
+ }
+ }
+ else
+ {
+ alternativeMaxHeight = std::max( alternativeMaxHeight, weightedMaxHeight );
+ }
+
if( !allFillParent && heightMode != MeasureSpec::Mode::EXACTLY )
{
maxHeight = alternativeMaxHeight;
void LinearLayout::MeasureVertical( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec )
{
auto widthMode = widthMeasureSpec.GetMode();
+ auto heightMode = heightMeasureSpec.GetMode();
+ bool isExactly = ( heightMode == MeasureSpec::Mode::EXACTLY );
bool matchWidth = false;
bool allFillParent = true;
LayoutLength maxWidth = 0;
LayoutLength alternativeMaxWidth = 0;
-
+ LayoutLength weightedMaxWidth = 0;
+ float totalWeight = 0;
+ int usedExcessSpace = 0;
struct
{
MeasuredSize::State widthState;
mTotalLength = 0;
// measure children, and determine if further resolution is required
- for( unsigned int i=0; i<GetChildCount(); ++i )
+
+ // 1st phase:
+ // We cycle through all children and measure children with weight 0 (non weighted children) according to their specs
+ // to accumulate total used space in mTotalLength based on measured sizes and margins.
+ // Weighted children are not measured at this phase.
+ // Available space for weighted children will be calculated in the phase 2 based on mTotalLength value.
+ for( unsigned int i = 0; i < GetChildCount(); ++i )
{
auto childLayout = GetChildAt( i );
if( childLayout )
{
auto childOwner = childLayout->GetOwner();
auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
-
- MeasureChildWithMargins( childLayout, widthMeasureSpec, 0, heightMeasureSpec, 0 );
- auto childHeight = childLayout->GetMeasuredHeight();
+ auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+ auto childWeight = childOwner.GetProperty<float>( Toolkit::LinearLayout::ChildProperty::WEIGHT );
auto childMargin = childLayout->GetMargin();
- auto length = childHeight + LayoutLength::IntType(childMargin.top + childMargin.bottom );
- auto cellPadding = i<GetChildCount()-1 ? mCellPadding.height : 0;
- auto totalLength = mTotalLength;
- mTotalLength = std::max( totalLength, totalLength + length + cellPadding);
+ totalWeight += childWeight;
+
+ bool useExcessSpace = desiredHeight == 0 && childWeight > 0;
+
+ if( isExactly && useExcessSpace )
+ {
+ LayoutLength totalLength = mTotalLength;
+ mTotalLength = std::max( totalLength, totalLength + childMargin.top + childMargin.bottom );
+ }
+ else
+ {
+ LayoutLength childHeight = 0;
+ if( useExcessSpace )
+ {
+ // The heightMode is either UNSPECIFIED or AT_MOST, and
+ // this child is only laid out using excess space. Measure
+ // using WRAP_CONTENT so that we can find out the view's
+ // optimal height. We'll restore the original height of 0
+ // after measurement.
+ auto padding = GetPadding();
+ const MeasureSpec childWidthMeasureSpec = GetChildMeasureSpec( widthMeasureSpec, padding.start + padding.end, desiredWidth );
+ const MeasureSpec childHeightMeasureSpec = GetChildMeasureSpec( heightMeasureSpec, padding.top + padding.bottom, Toolkit::ChildLayoutData::WRAP_CONTENT );
+ childLayout->Measure( childWidthMeasureSpec, childHeightMeasureSpec );
+ childHeight = childLayout->GetMeasuredHeight();
+ usedExcessSpace += childHeight;
+ }
+ else
+ {
+ MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
+ childHeight = childLayout->GetMeasuredHeight();
+ }
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LinearLayout::MeasureVertical childHeight(%d)\n", MeasureSpec::IntType( childHeight ) );
+
+ auto length = childHeight + LayoutLength::IntType( childMargin.top + childMargin.bottom );
+ auto cellPadding = i < GetChildCount() - 1 ? mCellPadding.height : 0;
+ auto totalLength = mTotalLength;
+ mTotalLength = std::max( totalLength, totalLength + length + cellPadding );
+ }
bool matchWidthLocally = false;
if( widthMode != MeasureSpec::Mode::EXACTLY && desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT )
maxWidth = std::max( maxWidth, childWidth );
allFillParent = ( allFillParent && desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT );
- alternativeMaxWidth = std::max( alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth );
+ if( childWeight > 0 )
+ {
+ /*
+ * Widths of weighted Views are bogus if we end up
+ * remeasuring, so keep them separate.
+ */
+ weightedMaxWidth = std::max( weightedMaxWidth, matchWidthLocally ? marginWidth : childWidth );
+ }
+ else
+ {
+ alternativeMaxWidth = std::max( alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth );
+ }
}
}
+
Extents padding = GetPadding();
mTotalLength += padding.top + padding.bottom;
auto heightSize = mTotalLength;
MeasuredSize heightSizeAndState = ResolveSizeAndState( heightSize, heightMeasureSpec, MeasuredSize::State::MEASURED_SIZE_OK);
heightSize = heightSizeAndState.GetSize();
+ // Either expand children with weight to take up available space or
+ // shrink them if they extend beyond our current bounds. If we skipped
+ // measurement on any children, we need to measure them now.
+
+ // 2nd phase:
+ // We cycle through weighted children now (children with weight > 0).
+ // The children are measured with exact size equal to their share of the available space based on their weights.
+ // mTotalLength is updated to include weighted children measured sizes.
+ int remainingExcess = heightSize - mTotalLength + usedExcessSpace;
+ if( remainingExcess != 0 && totalWeight > 0.0f )
+ {
+ float remainingWeightSum = totalWeight;
+
+ mTotalLength = 0;
+
+ for( unsigned int i = 0; i < GetChildCount(); ++i )
+ {
+ auto childLayout = GetChildAt( i );
+ auto childOwner = childLayout->GetOwner();
+ auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+ auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+ auto childWeight = childOwner.GetProperty<float>( Toolkit::LinearLayout::ChildProperty::WEIGHT );
+ auto childMargin = childLayout->GetMargin();
+
+ LayoutLength childHeight = 0;
+ if( childWeight > 0 )
+ {
+ int share = static_cast<int>( childWeight * remainingExcess / remainingWeightSum );
+ remainingExcess -= share;
+ remainingWeightSum -= childWeight;
+
+ // Always lay out weighted elements with intrinsic size regardless of the parent spec
+ // for consistency between specs.
+ if( desiredHeight == 0 )
+ {
+ // This child needs to be laid out from scratch using
+ // only its share of excess space.
+ childHeight = share;
+ }
+ else
+ {
+ // This child had some intrinsic width to which we
+ // need to add its share of excess space.
+ childHeight = childLayout->GetMeasuredHeight() + share;
+ }
+
+ const MeasureSpec childWidthMeasureSpec = GetChildMeasureSpec( widthMeasureSpec, padding.start + padding.end, desiredWidth );
+ const MeasureSpec childHeightMeasureSpec = MeasureSpec( childHeight, MeasureSpec::Mode::EXACTLY );
+ childLayout->Measure( childWidthMeasureSpec, childHeightMeasureSpec );
+
+ // Child may now not fit in vertical dimension.
+ if( childLayout->GetMeasuredHeightAndState().GetState() == MeasuredSize::State::MEASURED_SIZE_TOO_SMALL )
+ {
+ childState.heightState = MeasuredSize::State::MEASURED_SIZE_TOO_SMALL;
+ }
+ }
+
+ bool matchWidthLocally = false;
+ if( widthMode != MeasureSpec::Mode::EXACTLY && desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT )
+ {
+ // Will have to re-measure at least this child when we know exact height.
+ matchWidth = true;
+ matchWidthLocally = true;
+ }
+
+ auto marginWidth = LayoutLength( childMargin.start + childMargin.end );
+ auto childWidth = childLayout->GetMeasuredWidth() + marginWidth;
+ maxWidth = std::max( maxWidth, childWidth );
+ allFillParent = allFillParent && desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT;
+ alternativeMaxWidth = std::max( alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth );
+
+ childHeight = childLayout->GetMeasuredHeight();
+ auto length = childHeight + LayoutLength::IntType( childMargin.top + childMargin.bottom );
+ auto cellPadding = i < GetChildCount() - 1 ? mCellPadding.height : 0;
+ auto totalLength = mTotalLength;
+ mTotalLength = std::max( totalLength, totalLength + length + cellPadding );
+ }
+
+ // Add in our padding
+ mTotalLength += padding.top + padding.bottom;
+ }
+ else
+ {
+ alternativeMaxWidth = std::max( alternativeMaxWidth, weightedMaxWidth );
+ }
+
if( !allFillParent && widthMode != MeasureSpec::Mode::EXACTLY )
{
maxWidth = alternativeMaxWidth;