From ae45011bfee6c5b17f4468241bddf3620a6d62f2 Mon Sep 17 00:00:00 2001 From: Agnelo Vaz Date: Tue, 12 Jun 2018 17:22:41 +0100 Subject: [PATCH] Adding Absolute layout An layout that allows it's children to be positioned explictly. Use Actor::Property::POSITION to provide the position. The children can overlap and exceed their parent's boundary. Limitations The absolute layout does not have it's own Padding. Change-Id: I52d15128acd22250c90d993bb1a33afd738e1cbe --- automated-tests/src/dali-toolkit/CMakeLists.txt | 1 + .../src/dali-toolkit/utc-Dali-AbsoluteLayout.cpp | 121 +++++++++++++++ .../src/dali-toolkit/utc-Dali-Layouting.cpp | 17 ++- dali-toolkit/devel-api/file.list | 2 + .../devel-api/layouting/absolute-layout.cpp | 63 ++++++++ dali-toolkit/devel-api/layouting/absolute-layout.h | 109 ++++++++++++++ .../devel-api/layouting/layout-item-impl.cpp | 5 + .../devel-api/toolkit-property-index-ranges.h | 18 ++- dali-toolkit/internal/file.list | 1 + .../internal/layouting/absolute-layout-impl.cpp | 166 +++++++++++++++++++++ .../internal/layouting/absolute-layout-impl.h | 89 +++++++++++ 11 files changed, 576 insertions(+), 16 deletions(-) create mode 100644 automated-tests/src/dali-toolkit/utc-Dali-AbsoluteLayout.cpp create mode 100644 dali-toolkit/devel-api/layouting/absolute-layout.cpp create mode 100644 dali-toolkit/devel-api/layouting/absolute-layout.h create mode 100644 dali-toolkit/internal/layouting/absolute-layout-impl.cpp create mode 100644 dali-toolkit/internal/layouting/absolute-layout-impl.h diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index 6af88aa..c3bbf75 100755 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -7,6 +7,7 @@ SET(CAPI_LIB "dali-toolkit") # List of test case sources (Only these get parsed for test cases) SET(TC_SOURCES + utc-Dali-AbsoluteLayout.cpp utc-Dali-Alignment.cpp utc-Dali-AnimatedImageVisual.cpp utc-Dali-BloomView.cpp diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AbsoluteLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AbsoluteLayout.cpp new file mode 100644 index 0000000..e443b7e --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-AbsoluteLayout.cpp @@ -0,0 +1,121 @@ +/* + * 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 +#include +#include + +#include +#include +#include + +#include + +using namespace Dali; +using namespace Toolkit; + +void utc_dali_toolkit_absolute_layout_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void utc_dali_toolkit_absolute_layoutg_cleanup(void) +{ + test_return_value = TET_PASS; +} + + +int UtcDaliLayouting_AbsoluteLayoutDownCast(void) +{ + TestApplication application; + tet_infoline(" UtcDaliLayouting_AbsoluteLayoutDownCast - Testing Downcast"); + + AbsoluteLayout absoluteLayout = AbsoluteLayout::New(); + + LayoutGroup layoutGroup( absoluteLayout ); + + AbsoluteLayout absoluteLayoutCandidate = AbsoluteLayout::DownCast( layoutGroup ); + DALI_TEST_CHECK( absoluteLayoutCandidate ); + + END_TEST; +} + +int UtcDaliLayouting_AbsoluteLayoutAssignment(void) +{ + TestApplication application; + tet_infoline(" UtcDaliLayouting_AbsoluteLayoutAssignment - Testing operator="); + + AbsoluteLayout absoluteLayout = AbsoluteLayout::New(); + AbsoluteLayout absoluteLayout2; + + absoluteLayout2 = absoluteLayout; + + DALI_TEST_CHECK( absoluteLayout2 == absoluteLayout ); + + END_TEST; +} + + +int UtcDaliLayouting_AbsoluteLayout01(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_AbsoluteLayout01 - Position an item with Actor::Property::POSITION"); + + Stage stage = Stage::GetCurrent(); + auto absoluteLayout = Control::New(); + auto layout = AbsoluteLayout::New(); + DevelControl::SetLayout( absoluteLayout, layout ); + absoluteLayout.SetName( "AsoluteLayout"); + + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); + controls.push_back( CreateLeafControl( 100, 100 ) ); + controls.push_back( CreateLeafControl( 100, 100 ) ); + controls.push_back( CreateLeafControl( 100, 100 ) ); + + // Position one of the controls using the actor property. + controls[1].SetProperty(Actor::Property::POSITION, Vector3( 100.0f, 0.0f, 0.0f) ); + + for( auto&& iter : controls ) + { + absoluteLayout.Add( iter ); + } + absoluteLayout.SetParentOrigin( ParentOrigin::CENTER ); + absoluteLayout.SetAnchorPoint( AnchorPoint::CENTER ); + stage.Add( absoluteLayout ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + // AbsoluteLayout renders items at the positions given by their Actor::Property::POSITION relative to the top left of the container. + // Items can overlap or spill out of their parent container. + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // The controls[1] was the only control to have a defiend position + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + // Items size should not change regardless of parent's size. + DALI_TEST_EQUALS( controls[0].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp index fbc717c..e5a57b3 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -803,17 +804,17 @@ int UtcDaliLayouting_VboxLayout02(void) // LayoutGroup for this to happen automatically. // // For this test, add an hbox instead - auto hbox = Control::New(); - auto hboxLayout = HboxLayout::New(); - DevelControl::SetLayout( hbox, hboxLayout ); - hbox.SetName( "Hbox"); - stage.Add( hbox ); + auto rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "AbsoluteLayout"); + stage.Add( rootControl ); auto vbox = Control::New(); auto vboxLayout = VboxLayout::New(); DevelControl::SetLayout( vbox, vboxLayout ); vbox.SetName( "Vbox"); - hbox.Add( vbox ); + rootControl.Add( vbox ); vbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); vbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); @@ -840,8 +841,8 @@ int UtcDaliLayouting_VboxLayout02(void) application.SendNotification(); application.Render(); - DALI_TEST_EQUALS( hbox.GetProperty(Actor::Property::POSITION), Vector3(0,0,0),TEST_LOCATION); - DALI_TEST_EQUALS( hbox.GetProperty(Actor::Property::SIZE), Vector3(480,800,0),TEST_LOCATION); + DALI_TEST_EQUALS( rootControl.GetProperty(Actor::Property::POSITION), Vector3(0,0,0),TEST_LOCATION); + DALI_TEST_EQUALS( rootControl.GetProperty(Actor::Property::SIZE), Vector3(480,800,0),TEST_LOCATION); // vbox centers elements horizontally, it should wrap it's content horizontally, i.e. it should take the width of the largest element (100) DALI_TEST_EQUALS( vbox.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index 3e81854..52466e4 100755 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -32,6 +32,7 @@ devel_api_src_files = \ $(devel_api_src_dir)/image-loader/image-atlas.cpp \ $(devel_api_src_dir)/image-loader/texture-manager.cpp \ $(devel_api_src_dir)/layouting/flex-layout.cpp \ + $(devel_api_src_dir)/layouting/absolute-layout.cpp \ $(devel_api_src_dir)/layouting/hbox-layout.cpp \ $(devel_api_src_dir)/layouting/vbox-layout.cpp \ $(devel_api_src_dir)/layouting/layout-item.cpp \ @@ -81,6 +82,7 @@ devel_api_effects_view_header_files = \ $(devel_api_src_dir)/controls/effects-view/effects-view.h devel_api_layouting_header_files = \ + $(devel_api_src_dir)/layouting/absolute-layout.h \ $(devel_api_src_dir)/layouting/child-layout-data.h \ $(devel_api_src_dir)/layouting/flex-layout.h \ $(devel_api_src_dir)/layouting/hbox-layout.h \ diff --git a/dali-toolkit/devel-api/layouting/absolute-layout.cpp b/dali-toolkit/devel-api/layouting/absolute-layout.cpp new file mode 100644 index 0000000..1323b30 --- /dev/null +++ b/dali-toolkit/devel-api/layouting/absolute-layout.cpp @@ -0,0 +1,63 @@ +/* + * 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 + +//INTERNAL HEADERS +#include + +namespace Dali +{ +namespace Toolkit +{ + +AbsoluteLayout::AbsoluteLayout() +{ +} + +AbsoluteLayout AbsoluteLayout::New() +{ + Internal::AbsoluteLayoutPtr internal = Internal::AbsoluteLayout::New(); + return AbsoluteLayout( internal.Get() ); +} + +AbsoluteLayout AbsoluteLayout::DownCast( BaseHandle handle ) +{ + return AbsoluteLayout( dynamic_cast< Dali::Toolkit::Internal::AbsoluteLayout*>( handle.GetObjectPtr() ) ); +} + +AbsoluteLayout::AbsoluteLayout( const AbsoluteLayout& other ) +: LayoutGroup( other ) +{ +} + +AbsoluteLayout& AbsoluteLayout::operator=( const AbsoluteLayout& other ) +{ + if( &other != this ) + { + LayoutGroup::operator=( other ); + } + return *this; +} + +AbsoluteLayout::AbsoluteLayout( Dali::Toolkit::Internal::AbsoluteLayout* object ) +: LayoutGroup( object ) +{ +} + +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/devel-api/layouting/absolute-layout.h b/dali-toolkit/devel-api/layouting/absolute-layout.h new file mode 100644 index 0000000..b74b19d --- /dev/null +++ b/dali-toolkit/devel-api/layouting/absolute-layout.h @@ -0,0 +1,109 @@ +#ifndef DALI_TOOLKIT_LAYOUTING_ABSOLUTE_LAYOUT_H +#define DALI_TOOLKIT_LAYOUTING_ABSOLUTE_LAYOUT_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. + */ + +#include +#include +#include +#include +#include + +namespace Dali +{ +namespace Toolkit +{ + +namespace Internal DALI_INTERNAL +{ +class AbsoluteLayout; +} + +/** + * This class implements a absolute layout, allowing explict positioning of + * children. + * Positions are from the top left of the layout and can be set using the + * Actor::Property::POSITION and alike. + */ +class DALI_IMPORT_API AbsoluteLayout : public LayoutGroup +{ +public: + + enum PropertyRange + { + CHILD_PROPERTY_START_INDEX = ABSOLUTE_LAYOUT_CHILD_PROPERTY_START_INDEX, + CHILD_PROPERTY_END_INDEX = ABSOLUTE_LAYOUT_CHILD_PROPERTY_END_INDEX + }; + + /** + * @brief Creates an uninitialized AbsoluteLayout handle. + * + * Initialize it using AbsoluteLayout::New(). + * Calling member functions with an uninitialized handle is not allowed. + */ + AbsoluteLayout(); + + /** + * @brief Creates a AbsoluteLayout object. + */ + static AbsoluteLayout New(); + + /** + * @brief Downcasts a handle to a AbsoluteLayout handle. + * + * If handle points to a AbsoluteLayout, the downcast produces a valid handle. + * If not, the returned handle is left uninitialized. + + * @param[in] handle to an object + * @return Handle to a AbsoluteLayout or an uninitialized handle + */ + static AbsoluteLayout DownCast( BaseHandle handle ); + + /** + * @brief Copy constructor + */ + AbsoluteLayout( const AbsoluteLayout& other ); + + /** + * @brief Assigment operator + */ + AbsoluteLayout& operator=( const AbsoluteLayout& other ); + + /** + * @brief Default destructor. + * + * This is non-virtual, since derived Handle types must not contain data or virtual methods + */ + ~AbsoluteLayout()=default; + + +public: // Not intended for application developers + + /// @cond internal + /** + * @brief This constructor is used by AbsoluteLayout::New() methods. + * + * @param[in] actor A pointer to a newly allocated Dali resource + */ + explicit DALI_INTERNAL AbsoluteLayout( Internal::AbsoluteLayout* body ); + /// @endcond +}; + +} // namespace Toolkit +} // namespace Dali + +#endif // DALI_TOOLKIT_LAYOUTING_ABSOLUTE_LAYOUT_H diff --git a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp index 217ffa6..5336a7f 100644 --- a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp @@ -145,6 +145,11 @@ void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasur mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET ); // measure ourselves, this should set the measured dimension flag back +#if defined(DEBUG_ENABLED) + std::ostringstream o; + o<ClearPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT ); diff --git a/dali-toolkit/devel-api/toolkit-property-index-ranges.h b/dali-toolkit/devel-api/toolkit-property-index-ranges.h index c5db50c..1861a93 100644 --- a/dali-toolkit/devel-api/toolkit-property-index-ranges.h +++ b/dali-toolkit/devel-api/toolkit-property-index-ranges.h @@ -32,14 +32,16 @@ namespace Toolkit */ enum DevelPropertyRanges { - LAYOUT_GROUP_CHILD_PROPERTY_START_INDEX = CHILD_PROPERTY_REGISTRATION_START_INDEX + 1000, ///< Layout Group Property Start Index. - LAYOUT_GROUP_CHILD_PROPERTY_END_INDEX = LAYOUT_GROUP_CHILD_PROPERTY_START_INDEX + 999, ///< Layout Group Property End Index. - LINEAR_LAYOUT_CHILD_PROPERTY_START_INDEX = LAYOUT_GROUP_CHILD_PROPERTY_END_INDEX + 1, ///< Linear Layout Property Start Index. - LINEAR_LAYOUT_CHILD_PROPERTY_END_INDEX = LINEAR_LAYOUT_CHILD_PROPERTY_START_INDEX + 999, ///< Linear Layout Property End Index. - GRID_LAYOUT_CHILD_PROPERTY_START_INDEX = LINEAR_LAYOUT_CHILD_PROPERTY_END_INDEX + 1, ///< Grid Layout Property Start Index. - GRID_LAYOUT_CHILD_PROPERTY_END_INDEX = GRID_LAYOUT_CHILD_PROPERTY_START_INDEX + 999, ///< Grid Layout Property End Index. - FLEX_LAYOUT_CHILD_PROPERTY_START_INDEX = GRID_LAYOUT_CHILD_PROPERTY_END_INDEX + 1, ///< Flex Layout Property Start Index. - FLEX_LAYOUT_CHILD_PROPERTY_END_INDEX = FLEX_LAYOUT_CHILD_PROPERTY_START_INDEX + 999, ///< Flex Layout Property End Index. + LAYOUT_GROUP_CHILD_PROPERTY_START_INDEX = CHILD_PROPERTY_REGISTRATION_START_INDEX + 1000, ///< Layout Group Property Start Index. + LAYOUT_GROUP_CHILD_PROPERTY_END_INDEX = LAYOUT_GROUP_CHILD_PROPERTY_START_INDEX + 999, ///< Layout Group Property End Index. + LINEAR_LAYOUT_CHILD_PROPERTY_START_INDEX = LAYOUT_GROUP_CHILD_PROPERTY_END_INDEX + 1, ///< Linear Layout Property Start Index. + LINEAR_LAYOUT_CHILD_PROPERTY_END_INDEX = LINEAR_LAYOUT_CHILD_PROPERTY_START_INDEX + 999, ///< Linear Layout Property End Index. + GRID_LAYOUT_CHILD_PROPERTY_START_INDEX = LINEAR_LAYOUT_CHILD_PROPERTY_END_INDEX + 1, ///< Grid Layout Property Start Index. + GRID_LAYOUT_CHILD_PROPERTY_END_INDEX = GRID_LAYOUT_CHILD_PROPERTY_START_INDEX + 999, ///< Grid Layout Property End Index. + FLEX_LAYOUT_CHILD_PROPERTY_START_INDEX = GRID_LAYOUT_CHILD_PROPERTY_END_INDEX + 1, ///< Flex Layout Property Start Index. + FLEX_LAYOUT_CHILD_PROPERTY_END_INDEX = FLEX_LAYOUT_CHILD_PROPERTY_START_INDEX + 999, ///< Flex Layout Property End Index. + ABSOLUTE_LAYOUT_CHILD_PROPERTY_START_INDEX = FLEX_LAYOUT_CHILD_PROPERTY_END_INDEX +1, ///< Absolute Layout Property Start Index. + ABSOLUTE_LAYOUT_CHILD_PROPERTY_END_INDEX = ABSOLUTE_LAYOUT_CHILD_PROPERTY_START_INDEX + 999, ///< Absolute Layout Property End Index. }; } // namespace Toolkit diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 5421132..6442c6f 100755 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -12,6 +12,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/builder/tree-node-manipulator.cpp \ $(toolkit_src_dir)/builder/replacement.cpp \ $(toolkit_src_dir)/layouting/flex-layout-impl.cpp \ + $(toolkit_src_dir)/layouting/absolute-layout-impl.cpp \ $(toolkit_src_dir)/layouting/hbox-layout-impl.cpp \ $(toolkit_src_dir)/layouting/vbox-layout-impl.cpp \ $(toolkit_src_dir)/layouting/layout-item-data-impl.cpp \ diff --git a/dali-toolkit/internal/layouting/absolute-layout-impl.cpp b/dali-toolkit/internal/layouting/absolute-layout-impl.cpp new file mode 100644 index 0000000..abe424c --- /dev/null +++ b/dali-toolkit/internal/layouting/absolute-layout-impl.cpp @@ -0,0 +1,166 @@ +/* + * 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 + +//INTERNAL HEADERS +#include +#include +#include +#include +#include +#include + +namespace +{ +#if defined(DEBUG_ENABLED) +static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_LAYOUT" ); +#endif +} + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ + +AbsoluteLayoutPtr AbsoluteLayout::New() +{ + AbsoluteLayoutPtr layout( new AbsoluteLayout() ); + return layout; +} + +AbsoluteLayout::AbsoluteLayout() +: LayoutGroup() +{ +} + +AbsoluteLayout::~AbsoluteLayout() +{ +} + +void AbsoluteLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) +{ +#if defined(DEBUG_ENABLED) + auto actor = Actor::DownCast(GetOwner()); + + std::ostringstream oss; + oss << "AbsoluteLayout::OnMeasure "; + if( actor ) + { + oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " "; + } + oss << "widthMeasureSpec:" << widthMeasureSpec << " heightMeasureSpec:" << heightMeasureSpec << std::endl; + DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() ); +#endif + + LayoutLength totalHeight( 0 ); + LayoutLength totalWidth( 0 ); + + struct + { + MeasuredSize::State widthState; + MeasuredSize::State heightState; + } childState = { MeasuredSize::State::MEASURED_SIZE_OK, MeasuredSize::State::MEASURED_SIZE_OK }; + + auto minPosition = Vector3( Vector3::ZERO ); + auto maxPosition = Vector3( Vector3::ZERO ); + + // measure children + for( unsigned int i=0; iGetOwner(); + + // Get size of child + MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec ); + auto childWidth = childLayout->GetMeasuredWidth(); + auto childHeight = childLayout->GetMeasuredHeight(); + + // Determine the width and height needed by the children using their given position and size. + // Children could overlap so find the left most and right most child. + auto childPosition = childOwner.GetProperty< Vector3 >( Actor::Property::POSITION ); + minPosition.x = std::min( minPosition.x, childPosition.x ); + maxPosition.x = std::max( maxPosition.x, childPosition.x + childWidth ); + // Children could overlap so find the highest and lowest child. + minPosition.y = std::min( minPosition.y, childPosition.y ); + maxPosition.y = std::max( maxPosition.y, childPosition.y + childHeight ); + + // Store current width and height needed to contain all children. + totalWidth = maxPosition.x - minPosition.x; + totalHeight = maxPosition.y - minPosition.y; + DALI_LOG_INFO( gLogFilter, Debug::Concise, "AbsoluteLayout::OnMeasure child width(%f) height(%f) \n", (float)totalWidth, (float)totalHeight ); + + if( childLayout->GetMeasuredWidthAndState().GetState() == MeasuredSize::State::MEASURED_SIZE_TOO_SMALL ) + { + childState.widthState = MeasuredSize::State::MEASURED_SIZE_TOO_SMALL; + } + if( childLayout->GetMeasuredHeightAndState().GetState() == MeasuredSize::State::MEASURED_SIZE_TOO_SMALL ) + { + childState.heightState = MeasuredSize::State::MEASURED_SIZE_TOO_SMALL; + } + } + } + + MeasuredSize widthSizeAndState = ResolveSizeAndState( totalWidth, widthMeasureSpec, MeasuredSize::State::MEASURED_SIZE_OK); + MeasuredSize heightSizeAndState = ResolveSizeAndState( totalHeight, heightMeasureSpec, MeasuredSize::State::MEASURED_SIZE_OK); + totalWidth = widthSizeAndState.GetSize(); + totalHeight = heightSizeAndState.GetSize(); + + // Ensure layout respects it's given minimum size + totalWidth = std::max( totalWidth, GetSuggestedMinimumWidth() ); + totalHeight = std::max( totalHeight, GetSuggestedMinimumHeight() ); + + widthSizeAndState.SetState( childState.widthState ); + heightSizeAndState.SetState( childState.heightState ); + + SetMeasuredDimensions( ResolveSizeAndState( totalWidth, widthMeasureSpec, childState.widthState ), + ResolveSizeAndState( totalHeight, heightMeasureSpec, childState.heightState ) ); + +} + +void AbsoluteLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom ) +{ + // Absolute layout positions it's children at their Actor positions. + // Children could overlap or spill outside the parent, as is the nature of absolute positions. + auto count = GetChildCount(); + + for( unsigned int i = 0; i < count; i++) + { + LayoutItemPtr childLayout = GetChildAt( i ); + if( childLayout != nullptr ) + { + auto childOwner = childLayout->GetOwner(); + auto childWidth = childLayout->GetMeasuredWidth(); + auto childHeight = childLayout->GetMeasuredHeight(); + + auto childPosition = childOwner.GetProperty< Vector3 >( Actor::Property::POSITION ); + + auto childTop = childPosition.y; + auto childLeft = childPosition.x; + + childLayout->Layout( childLeft, childTop, childLeft + childWidth, childTop + childHeight ); + } + } +} + +} // namespace Internal +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/internal/layouting/absolute-layout-impl.h b/dali-toolkit/internal/layouting/absolute-layout-impl.h new file mode 100644 index 0000000..99fb3c8 --- /dev/null +++ b/dali-toolkit/internal/layouting/absolute-layout-impl.h @@ -0,0 +1,89 @@ +#ifndef DALI_TOOLKIT_INTERNAL_ABSOLUTE_LAYOUT_H +#define DALI_TOOLKIT_INTERNAL_ABSOLUTE_LAYOUT_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. + */ + +#include +#include +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ + +class AbsoluteLayout; +using AbsoluteLayoutPtr = IntrusivePtr; + +class AbsoluteLayout final : public LayoutGroup +{ +public: + static AbsoluteLayoutPtr New(); + +protected: + + /** + * Constructor + */ + AbsoluteLayout(); + + /** + * Destructor + */ + virtual ~AbsoluteLayout(); + + /** + * @copydoc LayoutItem::OnMeasure + */ + virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) override; + + /** + * @copydoc LayoutItem::OnLayout + */ + virtual void OnLayout( bool changed, LayoutLength l, LayoutLength t, LayoutLength r, LayoutLength b ) override; + +private: + AbsoluteLayout( const AbsoluteLayout& other ) = delete; + AbsoluteLayout& operator=( const AbsoluteLayout& other ) = delete; + + void ForceUniformHeight( int count, MeasureSpec widthMeasureSpec ); + +}; + +} // namespace Internal + +inline Internal::AbsoluteLayout& GetImplementation( Dali::Toolkit::AbsoluteLayout& handle ) +{ + DALI_ASSERT_ALWAYS( handle && "AbsoluteLayout handle is empty" ); + BaseObject& object = handle.GetBaseObject(); + return static_cast( object ); +} + +inline const Internal::AbsoluteLayout& GetImplementation( const Dali::Toolkit::AbsoluteLayout& handle ) +{ + DALI_ASSERT_ALWAYS( handle && "AbsoluteLayout handle is empty" ); + const BaseObject& object = handle.GetBaseObject(); + return static_cast( object ); +} + +} // namespace Toolkit +} // namespace Dali + +#endif // DALI_TOOLKIT_INTERNAL_ABSOLUTE_LAYOUT_H -- 2.7.4