Sets a MeasureSpecification on a Layout using the controls existing Resize Policy.
Needed when legacy (pre Layouts) containers are added to Layouts and still need
their existing Resize polcies to be obeyed.
Change-Id: I1a96cd459ab31aa778b18ebe0e417a01b158f8d3
utc-Dali-JsonParser.cpp
utc-Dali-KeyInputFocusManager.cpp
utc-Dali-Layouting.cpp
+ utc-Dali-LayoutingResizePolicy.cpp
utc-Dali-PageTurnView.cpp
utc-Dali-Script.cpp
utc-Dali-ScrollBar.cpp
DALI_TEST_EQUALS( imageView.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
DALI_TEST_EQUALS( imageView.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ tet_infoline("UtcDaliLayouting_HboxLayout - Change image (new size)");
url = CreateImageURL( Vector4( 0, 255, 0, 255), ImageDimensions( 200, 200 ) );
imageView.SetImage( url );
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-event-thread-callback.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/absolute-layout.h>
+#include <dali-toolkit/devel-api/layouting/linear-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali/devel-api/actors/actor-devel.h>
+
+#include <../custom-layout.h>
+
+#include <layout-utils.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+// Turns the given control into a Root layout control and adds it to the stage.
+void SetupRootLayoutControl( Control& rootControl )
+{
+ rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ rootControl.SetName( "RootAbsoluteLayout" );
+ Stage stage = Stage::GetCurrent();
+ stage.Add( rootControl );
+}
+
+} // unnamed namespace
+
+void utc_dali_toolkit_layouting_resize_policy_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_layouting_resize_policy_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+// Test setting of the MeasureSpecs with the legacy ResizePolicies
+
+int UtcDaliLayoutingResizePolicy_01(void)
+{
+ /*
+ Root
+ |
+ Control (LinearLayout Horizontal)
+ |
+ Control (LayoutingRequired)
+ |
+ Control (ResizePolicy::FILL_TO_PARENT)
+ |
+ LeafControl
+ */
+
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliLayoutingResizePolicy_01 - Set ResizePolicy FILL_TO_PARENT on Control");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ SetupRootLayoutControl( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+ DevelControl::SetLayout( hbox, hboxLayout );
+ hbox.SetName( "hBox" );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+ auto layoutingControl = Control::New();
+ layoutingControl.SetName( "layoutingRequiredControl" );
+ DevelControl::SetLayoutingRequired( layoutingControl, true );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.Add( layoutingControl );
+
+ auto control = Control::New();
+ control.SetName( "fillToParentControl" );
+ DevelControl::SetLayoutingRequired( control, true );
+ control.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ layoutingControl.Add( control );
+
+ std::vector< Control > controls;
+ controls.push_back( CreateLeafControl( 40, 40 ) );
+
+ for( auto&& iter : controls )
+ {
+ control.Add( iter );
+ }
+
+ rootControl.Add( hbox );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.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 );
+
+ END_TEST;
+}
+
+
+int UtcDaliLayoutingResizePolicy_02(void)
+{
+ /*
+ Root
+ |
+ Control (LinearLayout Horizontal)
+ |
+ Control (LayoutingRequired)
+ |
+ Control (ResizePolicy::FIT_TO_CHILDREN)
+ |
+ LeafControl
+ */
+
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliLayoutingResizePolicy_02 - Set ResizePolicy FIT_TO_CHILDREN on Control");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ SetupRootLayoutControl( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+ DevelControl::SetLayout( hbox, hboxLayout );
+ hbox.SetName( "hBox" );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+ auto layoutingControl = Control::New();
+ layoutingControl.SetName( "layoutingRequiredControl" );
+ DevelControl::SetLayoutingRequired( layoutingControl, true );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.Add( layoutingControl );
+
+ auto control = Control::New();
+ control.SetName( "fitToChildrenControl" );
+ DevelControl::SetLayoutingRequired( control, true );
+ control.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+ layoutingControl.Add( control );
+
+ std::vector< Control > controls;
+ controls.push_back( CreateLeafControl( 40, 40 ) );
+
+ for( auto&& iter : controls )
+ {
+ control.Add( iter );
+ }
+
+ rootControl.Add( hbox );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.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 );
+
+ END_TEST;
+}
+
+int UtcDaliLayoutingResizePolicy_03(void)
+{
+ /*
+ Root
+ |
+ Control (LinearLayout Horizontal)
+ |
+ Control (LayoutingRequired)
+ |
+ Control (ResizePolicy::SIZE_RELATIVE_TO_PARENT)
+ |
+ LeafControl
+ */
+
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliLayoutingResizePolicy_03 - Set ResizePolicy SIZE_RELATIVE_TO_PARENT on Control");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ SetupRootLayoutControl( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+ DevelControl::SetLayout( hbox, hboxLayout );
+ hbox.SetName( "hBox" );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+ auto layoutingControl = Control::New();
+ layoutingControl.SetName( "layoutingRequiredControl" );
+ DevelControl::SetLayoutingRequired( layoutingControl, true );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.Add( layoutingControl );
+
+ auto control = Control::New();
+ control.SetName( "fitToChildrenControl" );
+ DevelControl::SetLayoutingRequired( control, true );
+ control.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ control.SetSizeModeFactor( Vector3( 0.50f, 1.0f, 1.0f ) );
+ layoutingControl.Add( control );
+
+ std::vector< Control > controls;
+ controls.push_back( CreateLeafControl( 40, 40 ) );
+
+ for( auto&& iter : controls )
+ {
+ control.Add( iter );
+ }
+
+ rootControl.Add( hbox );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 240.0f, 800.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 );
+
+ END_TEST;
+}
+
+int UtcDaliLayoutingResizePolicy_04(void)
+{
+ /*
+ Root
+ |
+ Control (LinearLayout Horizontal)
+ |
+ Control (LayoutingRequired)
+ |
+ Control (ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT)
+ |
+ LeafControl
+ */
+
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliLayoutingResizePolicy_04 - Set ResizePolicy SIZE_FIXED_OFFSET_FROM_PARENT on Control");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ SetupRootLayoutControl( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+ DevelControl::SetLayout( hbox, hboxLayout );
+ hbox.SetName( "hBox" );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+ auto layoutingControl = Control::New();
+ layoutingControl.SetName( "layoutingRequiredControl" );
+ DevelControl::SetLayoutingRequired( layoutingControl, true );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.Add( layoutingControl );
+
+ auto control = Control::New();
+ control.SetName( "fitToChildrenControl" );
+ DevelControl::SetLayoutingRequired( control, true );
+ control.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
+ control.SetSizeModeFactor( Vector3( -100.0f, 10.0f, 0.0f ) );
+ layoutingControl.Add( control );
+
+ std::vector< Control > controls;
+ controls.push_back( CreateLeafControl( 40, 40 ) );
+
+ for( auto&& iter : controls )
+ {
+ control.Add( iter );
+ }
+
+ rootControl.Add( hbox );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 380.0f, 810.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 );
+
+ END_TEST;
+}
+
+int UtcDaliLayoutingResizePolicy_05(void)
+{
+ /*
+ Root
+ |
+ Control (LinearLayout Horizontal)
+ |
+ Control (LayoutingRequired)
+ |
+ Control (ResizePolicy::FIXED)
+ |
+ LeafControl
+ */
+
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliLayoutingResizePolicy_05 - Set ResizePolicy FIXED on Control");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ SetupRootLayoutControl( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+ DevelControl::SetLayout( hbox, hboxLayout );
+ hbox.SetName( "hBox" );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+ auto layoutingControl = Control::New();
+ layoutingControl.SetName( "layoutingRequiredControl" );
+ DevelControl::SetLayoutingRequired( layoutingControl, true );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ hbox.Add( layoutingControl );
+
+ auto control = Control::New();
+ control.SetName( "fitToChildrenControl" );
+ DevelControl::SetLayoutingRequired( control, true );
+ control.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+ control.SetSize( Vector3( 300.0f, 300.0f, 0.0f ) );
+ layoutingControl.Add( control );
+
+ std::vector< Control > controls;
+ controls.push_back( CreateLeafControl( 40, 40 ) );
+
+ for( auto&& iter : controls )
+ {
+ control.Add( iter );
+ }
+
+ rootControl.Add( hbox );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 300.0f, 300.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 );
+
+ END_TEST;
+}
\ No newline at end of file
#include <dali-toolkit/internal/layouting/layout-group-data-impl.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/layouting/size-negotiation-mapper.h>
namespace
{
}
#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 );
#if defined(DEBUG_ENABLED)
auto parent = Toolkit::Control::DownCast( GetOwner() );
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner control(%s) owner(%s)\n", control?control.GetName().c_str():"Invalid", parent?parent.GetName().c_str():"Invalid" );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner child control(%s) owner control(%s)\n",
+ control?control.GetName().c_str():"Invalid",
+ parent?parent.GetName().c_str():"Invalid" );
#endif
if( control ) // Can only support adding Controls, not Actors to layout
// If control behaviour flag set to Layout then set a LayoutGroup.
if( DevelControl::IsLayoutingRequired( control ) )
{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner Creating default LayoutGroup for control:%s\n", control?control.GetName().c_str():"Invalid" );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner Creating default LayoutGroup for control:%s\n",
+ control?control.GetName().c_str():"Invalid" );
childLayout = LayoutGroup::New( control );
}
else
{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner Creating default LayoutItem for control:%s\n", control?control.GetName().c_str():"Invalid" );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner Creating default LayoutItem for control:%s\n",
+ control?control.GetName().c_str():"Invalid" );
childLayout = LayoutItem::New( control );
+ childLayout->SetAnimateLayout( IsLayoutAnimated() ); // forces animation inheritance.
}
- childLayout->SetAnimateLayout( IsLayoutAnimated() ); // @todo this essentially forces animation inheritance. Bad?
- DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner control:" << control.GetName() <<
- " desiredWidth: " << control.GetNaturalSize().width << " desiredHeight:" << control.GetNaturalSize().height );
+ DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner child control:" << control.GetName() <<
+ " desiredWidth: " << control.GetNaturalSize().width <<
+ " desiredHeight:" << control.GetNaturalSize().height );
childControlDataImpl.SetLayout( *childLayout.Get() );
}
else
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner child(%s) already has a Layout\n", control.GetName().c_str() );
LayoutGroupPtr layoutGroup( dynamic_cast< LayoutGroup* >( childLayout.Get() ) );
if( !layoutGroup )
{
auto childLayout = GetChildAt( i );
if( childLayout )
{
- auto childOwner = childLayout->GetOwner();
+ auto childControl = Toolkit::Control::DownCast(childLayout->GetOwner());
+
+ // If child control has children check if a ResizePolicy is set on it. A LayoutItem could be a legacy container.
+ // A legacy container would need it's ResizePolicy to be applied as a MeasureSpec.
+
+ // Check below will be true for legacy containers and controls with layout required set.
+ // Other layouts will have their own OnMeasure (a checked requirement) hence not execute LayoutGroup::OnMeasure.
+ // Controls which have set layout required will not be legacy controls hence should not have a ResizePolicy set.
+ if( childControl.GetChildCount() > 0 )
+ {
+ // First pass, Static mappings that are not dependant on parent
+ SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( childControl, childLayout, Dimension::WIDTH );
+ SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( childControl, childLayout, Dimension::HEIGHT );
+ }
+
+ // Second pass, if any mappings were not possible due to parent size dependancies then calculate an exact desired size for child
+ if( true == childLayout->IsResizePolicyRequired() ) // No need to test child count as this flag would only be set if control had children.
+ {
+ // Get last stored width and height specifications for the child
+ LayoutLength desiredWidth = childControl.GetProperty<float>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+ LayoutLength desiredHeight = childControl.GetProperty<float>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+
+ DALI_LOG_INFO( gLogFilter, Debug::General, "LayoutGroup::MeasureChild Initial desired size pre ResizePolicy(%f,%f)\n", desiredWidth.AsInteger(), desiredHeight.AsInteger() );
+
+ childLayout->SetResizePolicyRequired( false ); // clear flag incase in case of changes before next Measure
+ SizeNegotiationMapper::GetSizeofChildForParentDependentResizePolicy( childControl, widthMeasureSpec, heightMeasureSpec, desiredWidth, desiredHeight );
+
+ // Parent dependant ResizePolicies become exact sizes so are now set on the child before it's measured.
+ childControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, desiredWidth.AsInteger() );
+ childControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, desiredHeight.AsInteger() );
+
+ DALI_LOG_INFO( gLogFilter, Debug::General, " LayoutGroup::OnMeasure ResizePolicy Required resulting size(%f,%f)\n", desiredWidth.AsInteger(), desiredHeight.AsInteger() );
+ }
// Get size of child
MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
LayoutLength childWidth = childLayout->GetMeasuredWidth();
LayoutLength childHeight = childLayout->GetMeasuredHeight();
+
Extents childMargin = childLayout->GetMargin();
- DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure child width[" << childWidth << "] height[" << childHeight << "]\n" );
+ DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure child " << childControl.GetName().c_str() << " width[" << childWidth << "] height[" << childHeight << "]\n" );
layoutWidth = std::max( layoutWidth, childWidth + childMargin.start + childMargin.end );
layoutHeight = std::max( layoutHeight, childHeight + childMargin.top + childMargin.bottom );
}
else
{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure Not a layout\n" );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure Not a layout\n" );
}
}
const bool needsLayout = specChanged && ( !isSpecExactly || !matchesSpecSize );
- DALI_LOG_STREAM( gLayoutFilter, Debug::General, "LayoutItem::Measure("<<widthMeasureSpec<<", "<<heightMeasureSpec<<") Owner:"<<Actor::DownCast(GetOwner()).GetName() <<" forceLayout="<<forceLayout<<", specChanged="<<specChanged<<", isSpecExactly="<<isSpecExactly<<", matchesSpecSize="<<matchesSpecSize<<", needsLayout="<<needsLayout <<std::endl <<(forceLayout||needsLayout?" Remeasuring":" NoChange"));
+ DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::Measure("<<widthMeasureSpec<<", "<<heightMeasureSpec<<") Owner:"
+ <<Actor::DownCast(GetOwner()).GetName() <<" forceLayout="<<forceLayout
+ <<", specChanged="<<specChanged<<", isSpecExactly="<<isSpecExactly
+ <<", matchesSpecSize="<<matchesSpecSize
+ <<", needsLayout="<<needsLayout <<(forceLayout||needsLayout?" Remeasuring":" NoChange"));
if( forceLayout || needsLayout )
{
auto specMode = measureSpec.GetMode();
auto specSize = measureSpec.GetSize();
+ DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultSize MeasureSpec("<<measureSpec<< ") size:" << size << "\n" );
+
switch (specMode)
{
case MeasureSpec::Mode::UNSPECIFIED:
}
case MeasureSpec::Mode::AT_MOST:
{
+ // Ensure the default size does not exceed the spec size unless the default size is 0.
+ // Another container could provide a default size of 0.
LayoutLength tmp = specSize;
- if( size < tmp )
+
+ // Do not set size to 0, use specSize in this case as could be a legacy container
+ if( size < tmp && size > LayoutLength( 0 ) )
{
result = size;
}
break;
}
}
+ DALI_LOG_STREAM( gLayoutFilter, Debug::General, "LayoutItem::GetDefaultSize setting default size:" << result << "\n" );
return result;
}
{
DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::OnMeasure\n");
+ // GetDefaultSize will limit the MeasureSpec to the suggested minimumWidth and minimumHeight
SetMeasuredDimensions( GetDefaultSize( GetSuggestedMinimumWidth(), widthMeasureSpec ),
GetDefaultSize( GetSuggestedMinimumHeight(), heightMeasureSpec ) );
}
mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
}
+bool LayoutItem::IsResizePolicyRequired() const
+{
+ return mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
+}
+
+void LayoutItem::SetResizePolicyRequired( bool resizePolicyRequired )
+{
+ if( resizePolicyRequired )
+ {
+ mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
+ }
+ else
+ {
+ mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
+ }
+}
+
void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight )
{
- DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetMeasuredDimensions width(" << measuredWidth.GetSize() << ") height(" << measuredHeight.GetSize() << ") \n" );
+
+ DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetMeasuredDimensions width(" << measuredWidth.GetSize() << ") height(" << measuredHeight.GetSize() << ") Control:" <<
+ ( ( Actor::DownCast( GetOwner()) ) ? Actor::DownCast(GetOwner()).GetName().c_str() : "Invalid Actor" ) << "\n" );
mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET );
mImpl->mMeasuredWidth = measuredWidth;
*/
void SetLayoutRequested();
+ /**
+ * @brief Checks if the Resize policy is being used for this LayoutItem
+ * @return true is ResizePolicy is used
+ */
+ bool IsResizePolicyRequired() const;
+
+ /**
+ * @brief Sets if the ResizePolicy is needed or not for this LayoutItem
+ * @param[in] resizeRequired true or false flag
+ */
+ void SetResizePolicyRequired( bool resizeRequired );
+
/**
* @brief Get the measured width (without any measurement flags).
*
#if defined(DEBUG_ENABLED)
Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
+Debug::Filter* gLogFilterLayout = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT");
#endif
void Control::Impl::SetLayout( Toolkit::Internal::LayoutItem& layout )
{
+ DALI_LOG_INFO( gLogFilterLayout, Debug::Verbose, "Control::SetLayout control:%s existing layout:%s\n",
+ mControlImpl.Self().GetName().c_str(),
+ mLayout?"true":"false" );
+
if( mLayout )
{
mLayout->Unparent();
$(toolkit_src_dir)/layouting/layout-group-data-impl.cpp \
$(toolkit_src_dir)/layouting/layout-controller-debug.cpp \
$(toolkit_src_dir)/layouting/layout-controller-impl.cpp \
+ $(toolkit_src_dir)/layouting/size-negotiation-mapper.cpp \
$(toolkit_src_dir)/visuals/animated-image/animated-image-visual.cpp \
$(toolkit_src_dir)/visuals/animated-image/image-cache.cpp \
$(toolkit_src_dir)/visuals/animated-image/fixed-image-cache.cpp \
static const int PRIVATE_FLAG_IS_LAID_OUT = 0x00000008;
static const int PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT = 0x00000010; ///< Flag indicating that a call to measure() was skipped and should be done instead when layout() is invoked.
static const int PRIVATE_FLAG_FORCE_SET_FRAME = 0x00000020;
+ static const int PRIVATE_FLAG_USE_RESIZE_POLICY = 0x00000040;
int mViewFlags;
int mPrivateFlags;
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/layouting/size-negotiation-mapper.h>
+
+// EXTERNAL HEADER
+#include <dali/integration-api/debug.h>
+
+// INTERNAL HEADER
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/child-layout-data.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" );
+#endif
+
+/**
+ * Set the width specification with the given layout params
+ */
+void SetWidthLayoutParams( Dali::Toolkit::Control control, int layoutParams )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy Setting WIDTH LayoutParam(%d) for %s\n",
+ layoutParams,
+ control.GetName().c_str() );
+ control.SetProperty( Dali::Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, layoutParams );
+}
+
+/**
+ * Set the height specification with the given layout params
+ */
+void SetHeightLayoutParams( Dali::Toolkit::Control control, int layoutParams )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy Setting HEIGHT LayoutParam(%d) for %s\n",
+ layoutParams,
+ control.GetName().c_str() );
+ control.SetProperty( Dali::Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, layoutParams );
+}
+
+/**
+ * Call SetResizePolicyRequired true on the layout belonging to the provided control
+ */
+void SetResizePolicyRequiredFlag( Dali::Toolkit::Internal::LayoutItemPtr layout )
+{
+ layout->SetResizePolicyRequired( true );
+}
+
+} // namspace
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+void SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( Toolkit::Control control, Toolkit::Internal::LayoutItemPtr layout, Dimension::Type dimension )
+{
+ // Get control's current width specification
+ int matchedLayoutParamWidth = control.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+ int matchedLayoutParamHeight = control.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+
+ // Get control's Resize Policy that should be mapped to a width specification
+ const ResizePolicy::Type resizePolicy = control.GetResizePolicy( dimension );
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy ResizePolicy for control:%s resizePolicy %d for dimension %d\n",
+ control?control.GetName().c_str():"Invalid",
+ resizePolicy,
+ dimension );
+
+ bool matchFound( false );
+
+ // Use the control's ResizePolicy to determine the new specification
+ switch( resizePolicy )
+ {
+ case ResizePolicy::USE_ASSIGNED_SIZE :
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy USE_ASSIGNED_SIZE\n");
+ // Set by legacy controls on their children. Will not be exposed to a Layout.
+ break;
+ }
+
+ case ResizePolicy::FIXED :
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy FIXED\n");
+ Vector3 controlSize = control.GetTargetSize();
+ matchedLayoutParamWidth = controlSize.width;
+ matchedLayoutParamHeight = controlSize.height;
+ matchFound = true;
+ break;
+ };
+ case ResizePolicy::USE_NATURAL_SIZE :
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy USE_NATURAL_SIZE\n");
+ // Default ResizePolicy for controls.
+ // LayoutGroups are containers, containers will not have a natural size.
+ break;
+ };
+ case ResizePolicy::FILL_TO_PARENT :
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy FILL_TO_PARENT\n");
+ matchedLayoutParamWidth = ChildLayoutData::MATCH_PARENT;
+ matchedLayoutParamHeight = ChildLayoutData::MATCH_PARENT;
+ matchFound = true;
+ break;
+ };
+ case ResizePolicy::SIZE_RELATIVE_TO_PARENT :
+ {
+ SetResizePolicyRequiredFlag( layout ); // Defer setting the exact size until the parent size is known.
+ break;
+ };
+ case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT :
+ {
+ SetResizePolicyRequiredFlag( layout ); // Defer setting the exact size until the parent size is known.
+ break;
+ };
+ case ResizePolicy::FIT_TO_CHILDREN :
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy FIT_TO_CHILDREN\n");
+ matchedLayoutParamWidth = ChildLayoutData::WRAP_CONTENT;
+ matchedLayoutParamHeight = ChildLayoutData::WRAP_CONTENT;
+ matchFound = true;
+ break;
+ };
+ case ResizePolicy::DIMENSION_DEPENDENCY :
+ {
+ // Not supported
+ break;
+ };
+ }
+
+ // Use the resize policy for the required dimensions only.
+ // Possible that only one dimension was set hence either the matchedLayoutParamWidth or
+ // matchedLayoutParamHeight should not be used.
+ if( matchFound )
+ {
+ if( dimension == Dimension::WIDTH )
+ {
+ SetWidthLayoutParams( control, matchedLayoutParamWidth );
+ }
+ else if( dimension == Dimension::HEIGHT )
+ {
+ SetHeightLayoutParams( control, matchedLayoutParamHeight );
+ }
+ else if( Dimension::ALL_DIMENSIONS )
+ {
+ SetWidthLayoutParams( control, matchedLayoutParamWidth );
+ SetHeightLayoutParams( control, matchedLayoutParamHeight );
+ }
+ }
+};
+
+void SizeNegotiationMapper::GetSizeofChildForParentDependentResizePolicy( Toolkit::Control control, const MeasureSpec parentWidthSpecification, const MeasureSpec parentHeightSpecification, LayoutLength& childWidth, LayoutLength& childHeight)
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy ResizePolicy required for %s\n", control.GetName().c_str() );
+ ResizePolicy::Type widthResizePolicy = control.GetResizePolicy( Dimension::WIDTH );
+ ResizePolicy::Type heightResizePolicy = control.GetResizePolicy( Dimension::HEIGHT );
+ Vector3 sizeModeFactor = control.GetSizeModeFactor();
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::MeasureChild SetLayoutParamsForParentDependantResizePolicy for control:%s resizePolicy w:%d h:%d modeFactor(%f,%f,%f)\n",
+ control?control.GetName().c_str():"Invalid",
+ widthResizePolicy, heightResizePolicy,
+ sizeModeFactor.x,
+ sizeModeFactor.y,
+ sizeModeFactor.z );
+
+ if( widthResizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy width SIZE_RELATIVE_TO_PARENT\n");
+ childWidth = parentWidthSpecification.GetSize().AsDecimal() * sizeModeFactor.x;
+ }
+ else if( widthResizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy width SIZE_FIXED_OFFSET_FROM_PARENT\n");
+ childWidth = parentWidthSpecification.GetSize().AsDecimal() + sizeModeFactor.x;
+ }
+
+ if( heightResizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy height SIZE_RELATIVE_TO_PARENT\n");
+ childHeight = parentHeightSpecification.GetSize().AsDecimal() * sizeModeFactor.y;
+ }
+ else if( heightResizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy height SIZE_FIXED_OFFSET_FROM_PARENT\n");
+ childHeight = parentHeightSpecification.GetSize().AsDecimal() + sizeModeFactor.y;
+ }
+
+ // DIMENSION_DEPENDENCY not supported
+
+ DALI_LOG_INFO( gLogFilter, Debug::General, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy child size(%f,%f)\n", childWidth.AsInteger(), childHeight.AsInteger() );
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_SIZE_NEGOTIATION_MAPPER_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_LAYOUTING_SIZE_NEGOTIATION_MAPPER_IMPL_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL HEADERS
+#include <dali/public-api/actors/actor-enumerations.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+using LayoutItemPtr = IntrusivePtr<LayoutItem>;
+/**
+ * @brief Maps ResizePolicies used in SizeNegotiation to the Layout system
+ *
+ */
+namespace SizeNegotiationMapper
+{
+/**
+ * @brief Sets the child layout parameters on the control by mapping it's ResizePolicy to a MeasureSpecification
+ * @param[out] control the control to set the layout params on
+ * @param[out] layout the layout for the given control
+ * @param[in] dimension the dimension or dimensions the resize policy applies to.
+ */
+void SetLayoutParametersUsingResizePolicy( Toolkit::Control control, Toolkit::Internal::LayoutItemPtr layout, const Dimension::Type dimension );
+
+/**
+ * @brief Sets the child layout parameters on the control using the a ResizePolicy that is dependant on it's parent
+ * @note This method should be used after a child has been parented and a parent measure spec is available.
+ * @param[out] control the control to set the layout params on
+ * @param[in] parentWidthSpecification the parent's width measure specification
+ * @param[in] parentHeightSpecification the parent's height measure specification
+ * @param[out] childWidth the resulting child width
+ * @param[out] childHeight the resulting child height
+ */
+void GetSizeofChildForParentDependentResizePolicy( Toolkit::Control control, const MeasureSpec parentWidthSpecification, const MeasureSpec parentHeightSpecification, LayoutLength& childWidth, LayoutLength& childHeight );
+
+} // namespace SizeNegotiationMapper
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+#endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_SIZE_NEGOTIATION_MAPPER_IMPL_H
\ No newline at end of file
Vector3 Control::GetNaturalSize()
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::GetNaturalSize for %s\n", Self().GetName().c_str() );
Toolkit::Visual::Base visual = mImpl->GetVisual( Toolkit::Control::Property::BACKGROUND );
if( visual )
{