utc-Dali-FlexContainer.cpp
utc-Dali-FlexLayout.cpp
utc-Dali-GaussianBlurView.cpp
+ utc-Dali-GridLayout.cpp
utc-Dali-ImageView.cpp
utc-Dali-ImageVisual.cpp
utc-Dali-JsonParser.cpp
--- /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/grid.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+
+#include <../custom-layout.h>
+
+#include <layout-utils.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+void utc_dali_toolkit_grid_layouting_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_grid_layouting_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int UtcDaliLayouting_GridLayout01(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliLayouting_GridLayout01 2 Column, 4 Items");
+
+ const auto NUMBER_OF_COLUMNS = 2;
+ const auto NUMBER_OF_ITEMS = 4;
+
+ tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ rootControl.SetName( "AbsoluteLayout" );
+ stage.Add( rootControl );
+
+ auto gridContainer = Control::New();
+ auto gridLayout = Grid::New();
+ gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+ gridContainer.SetName( "GridLayout");
+ DevelControl::SetLayout( gridContainer, gridLayout );
+ gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+
+ std::vector< Control > controls;
+ for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+ {
+ controls.push_back( CreateLeafControl( 100, 100 ) );
+ }
+
+ for( auto&& iter : controls )
+ {
+ gridContainer.Add( iter );
+ }
+
+ rootControl.Add( gridContainer );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ // Grid will layout first 2 items on first row then last 2 on second row.
+ 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( 100.0f, 0.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( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Item sizes will not be changed
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.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 );
+
+ tet_printf( "Confirm number of columns is as set\n");
+ DALI_TEST_EQUALS( gridLayout.GetNumberOfColumns(), NUMBER_OF_COLUMNS, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliLayouting_GridLayout02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliLayouting_GridLayout02");
+
+ const auto NUMBER_OF_COLUMNS = 3;
+ const auto NUMBER_OF_ITEMS = 7;
+
+ tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ rootControl.SetName( "AbsoluteLayout" );
+ stage.Add( rootControl );
+
+ auto gridContainer = Control::New();
+ auto gridLayout = Grid::New();
+ gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+ gridContainer.SetName( "GridLayout");
+ DevelControl::SetLayout( gridContainer, gridLayout );
+ gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+
+ std::vector< Control > controls;
+ for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+ {
+ controls.push_back( CreateLeafControl( 100, 100 ) );
+ }
+
+ for( auto&& iter : controls )
+ {
+ gridContainer.Add( iter );
+ }
+
+ rootControl.Add( gridContainer );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ // grid layouts out 3 items per row, which is 480x800.
+ // Row 1
+ 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( 100.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 200.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ // Row 2
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[4].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[5].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 200.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ // Row 3
+ DALI_TEST_EQUALS( controls[6].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.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 );
+ DALI_TEST_EQUALS( controls[4].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[5].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[6].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliLayouting_GridLayout03(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliLayouting_GridLayout03 Grid Padding");
+
+ const auto NUMBER_OF_COLUMNS = 2;
+ const auto NUMBER_OF_ITEMS = 4;
+
+ tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+ Extents GRID_PADDING( Extents( 10, 10, 20, 20 ) ); // start,end,top,bottom
+
+ tet_printf( "Testing with Padding 10,10,20,20\n");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ rootControl.SetName( "AbsoluteLayout" );
+ stage.Add( rootControl );
+
+ auto gridContainer = Control::New();
+ auto gridLayout = Grid::New();
+ gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+ gridContainer.SetName( "GridLayout");
+ DevelControl::SetLayout( gridContainer, gridLayout );
+ gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ gridContainer.SetProperty( Control::Property::PADDING, GRID_PADDING );
+
+ std::vector< Control > controls;
+ for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+ {
+ controls.push_back( CreateLeafControl( 100, 100 ) );
+ }
+
+ for( auto&& iter : controls )
+ {
+ gridContainer.Add( iter );
+ }
+
+ rootControl.Add( gridContainer );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline(" UtcDaliLayouting_GridLayout03 Grid Padding 2 Column, 4 Items");
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f + GRID_PADDING.start , 0.0f + GRID_PADDING.top, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f + GRID_PADDING.start, 0.0f + GRID_PADDING.top, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f + GRID_PADDING.start, 100.0f + GRID_PADDING.top , 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f + GRID_PADDING.start, 100.0f + GRID_PADDING.top, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ tet_infoline(" UtcDaliLayouting_GridLayout03 Size of Grid should include padding");
+ DALI_TEST_EQUALS( gridContainer.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f * NUMBER_OF_COLUMNS + GRID_PADDING.start + + GRID_PADDING.end,
+ 100.0f * ( NUMBER_OF_ITEMS / NUMBER_OF_COLUMNS ) +
+ GRID_PADDING.top + GRID_PADDING.bottom,
+ 0.0f ), 0.0001f, TEST_LOCATION );
+
+ tet_infoline(" UtcDaliLayouting_GridLayout03 Item sizes unchanged");
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.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 );
+
+ END_TEST;
+}
+
+int UtcDaliLayouting_GridLayout04(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliLayouting_GridLayout04 Child Margin");
+
+ const auto NUMBER_OF_COLUMNS = 2;
+ const auto NUMBER_OF_ITEMS = 4;
+
+ tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+ Extents GRID_PADDING( Extents( 10, 10, 20, 20 ) ); // start,end,top,bottom
+ Extents ITEM_MARGIN( Extents( 10, 10, 5, 5 ) ); // start,end,top,bottom
+
+ tet_printf( "Testing with Margin 10,10,5,5\n");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ rootControl.SetName( "AbsoluteLayout" );
+ stage.Add( rootControl );
+
+ auto gridContainer = Control::New();
+ auto gridLayout = Grid::New();
+ gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+ gridContainer.SetName( "GridLayout");
+ DevelControl::SetLayout( gridContainer, gridLayout );
+ gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ gridContainer.SetProperty( Control::Property::PADDING, GRID_PADDING );
+
+ std::vector< Control > controls;
+ for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+ {
+ auto control = CreateLeafControl( 100, 100 );
+ control.SetProperty(Toolkit::Control::Property::MARGIN, ITEM_MARGIN );
+ controls.push_back( control );
+ }
+
+ for( auto&& iter : controls )
+ {
+ gridContainer.Add( iter );
+ }
+
+ rootControl.Add( gridContainer );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ),
+ Vector3( 0.0f + GRID_PADDING.start + ITEM_MARGIN.start,
+ 0.0f + GRID_PADDING.top + ITEM_MARGIN.top,
+ 0.0f ),
+ 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ),
+ Vector3( 100.0f + GRID_PADDING.start + ITEM_MARGIN.start *2 + ITEM_MARGIN.end,
+ 0.0f + GRID_PADDING.top + ITEM_MARGIN.top,
+ 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ),
+ Vector3( 0.0f + GRID_PADDING.start + ITEM_MARGIN.start,
+ 100.0f + GRID_PADDING.top + ITEM_MARGIN.top*2 + ITEM_MARGIN.bottom,
+ 0.0f ), 0.0001f, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ),
+ Vector3( 100.0f + GRID_PADDING.start + ITEM_MARGIN.start*2 + ITEM_MARGIN.end,
+ 100.0f + GRID_PADDING.top + ITEM_MARGIN.top*2 + ITEM_MARGIN.bottom,
+ 0.0f ), 0.0001f, TEST_LOCATION );
+
+ tet_infoline(" UtcDaliLayouting_GridLayout03 Size of Grid should include padding and margins");
+
+ const auto NUMBER_OF_ROWS = ( NUMBER_OF_ITEMS / NUMBER_OF_COLUMNS );
+
+ DALI_TEST_EQUALS( gridContainer.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f * NUMBER_OF_COLUMNS + GRID_PADDING.start + GRID_PADDING.end +
+ ITEM_MARGIN.start *NUMBER_OF_COLUMNS + ITEM_MARGIN.end *NUMBER_OF_COLUMNS,
+ 100.0f * NUMBER_OF_ROWS +
+ GRID_PADDING.top + GRID_PADDING.bottom +
+ ITEM_MARGIN.bottom *NUMBER_OF_ROWS + ITEM_MARGIN.bottom *NUMBER_OF_ROWS,
+ 0.0f ), 0.0001f, TEST_LOCATION );
+
+ tet_infoline(" UtcDaliLayouting_GridLayout03 Item sizes unchanged");
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.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 );
+
+ END_TEST;
+}
+
+
+int UtcDaliLayouting_GridLayoutDownCast(void)
+{
+ TestApplication application;
+ tet_infoline(" UtcDaliLayouting_GridLayoutDownCast - Testing Downcast");
+
+ Grid gridLayout = Grid::New();
+
+ LayoutGroup layoutGroup( gridLayout );
+
+ Grid gridLayoutCandidate = Grid::DownCast( layoutGroup );
+ DALI_TEST_CHECK( gridLayoutCandidate );
+
+ END_TEST;
+}
\ No newline at end of file
$(devel_api_src_dir)/layouting/flex-layout.cpp \
$(devel_api_src_dir)/layouting/absolute-layout.cpp \
$(devel_api_src_dir)/layouting/linear-layout.cpp \
+ $(devel_api_src_dir)/layouting/grid.cpp \
$(devel_api_src_dir)/layouting/layout-item.cpp \
$(devel_api_src_dir)/layouting/layout-item-impl.cpp \
$(devel_api_src_dir)/layouting/layout-controller.cpp \
$(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/grid.h \
$(devel_api_src_dir)/layouting/linear-layout.h \
$(devel_api_src_dir)/layouting/layout-child-impl.h \
$(devel_api_src_dir)/layouting/layout-controller.h \
--- /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/devel-api/layouting/grid.h>
+
+//EXTERNAL HEADERS
+//INTERNAL HEADERS
+#include <dali-toolkit/internal/layouting/grid-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+
+Grid::Grid()
+{
+}
+
+Grid Grid::New()
+{
+ Internal::GridPtr internal = Internal::Grid::New();
+ return Grid( internal.Get() );
+}
+
+Grid Grid::DownCast( BaseHandle handle )
+{
+ return Grid( dynamic_cast< Dali::Toolkit::Internal::Grid*>( handle.GetObjectPtr() ) );
+}
+
+Grid::Grid( const Grid& other )
+: LayoutGroup( other )
+{
+}
+
+Grid& Grid::operator=( const Grid& other )
+{
+ if( &other != this )
+ {
+ LayoutGroup::operator=( other );
+ }
+ return *this;
+}
+
+void Grid::SetNumberOfColumns( int columns )
+{
+ GetImplementation(*this).SetNumberOfColumns( columns );
+}
+
+int Grid::GetNumberOfColumns() const
+{
+ return GetImplementation(*this).GetNumberOfColumns();
+}
+
+Grid::Grid( Dali::Toolkit::Internal::Grid* object )
+: LayoutGroup( object )
+{
+}
+
+} // namespace Toolkit
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_TOOLKIT_LAYOUTING_GRID_LAYOUT_H
+#define DALI_TOOLKIT_LAYOUTING_GRID_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 <dali/public-api/common/dali-common.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali-toolkit/devel-api/layouting/layout-group.h>
+#include <dali-toolkit/devel-api/layouting/layout-size.h>
+#include <dali-toolkit/public-api/toolkit-property-index-ranges.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class Grid;
+}
+
+/**
+ * @brief
+ * This class implements a horizontal box layout, automatically handling
+ * right to left or left to right direction change.
+ */
+class DALI_TOOLKIT_API Grid : public LayoutGroup
+{
+public:
+
+ /**
+ * @brief Creates an uninitialized Grid handle.
+ *
+ * Initialize it using Grid::New().
+ * Calling member functions with an uninitialized handle is not allowed.
+ */
+ Grid();
+
+ /**
+ * @brief Creates a Grid object.
+ */
+ static Grid New();
+
+ /**
+ * @brief Downcasts a handle to a Grid handle.
+ *
+ * If handle points to a Grid, the downcast produces a valid handle.
+ * If not, the returned handle is left uninitialized.
+
+ * @param[in] handle to an object
+ * @return Handle to a Grid or an uninitialized handle
+ */
+ static Grid DownCast( BaseHandle handle );
+
+ /**
+ * @brief Copy constructor
+ */
+ Grid( const Grid& other );
+
+ /**
+ * @brief Assigment operator
+ */
+ Grid& operator=( const Grid& other );
+
+ /**
+ * @brief Default destructor.
+ *
+ * This is non-virtual, since derived Handle types must not contain data or virtual methods
+ */
+ ~Grid()=default;
+
+ /**
+ * @brief Set the number of columns in the Grid.
+ * @param[in] columns number of columns,
+ */
+ void SetNumberOfColumns( int columns );
+
+ /**
+ * @brief Get the number of columns in the grid.
+ * @return the number of columns.
+ */
+ int GetNumberOfColumns() const;
+
+public: // Not intended for application developers
+
+ /// @cond internal
+ /**
+ * @brief This constructor is used by Grid::New() methods.
+ *
+ * @param[in] actor A pointer to a newly allocated Dali resource
+ */
+ explicit DALI_INTERNAL Grid( Internal::Grid* body );
+ /// @endcond
+};
+
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_LAYOUTING_GRID_LAYOUT_H
$(toolkit_src_dir)/layouting/flex-layout-impl.cpp \
$(toolkit_src_dir)/layouting/absolute-layout-impl.cpp \
$(toolkit_src_dir)/layouting/linear-layout-impl.cpp \
+ $(toolkit_src_dir)/layouting/grid-locations.cpp \
+ $(toolkit_src_dir)/layouting/grid-impl.cpp \
$(toolkit_src_dir)/layouting/layout-item-data-impl.cpp \
$(toolkit_src_dir)/layouting/layout-group-data-impl.cpp \
$(toolkit_src_dir)/layouting/layout-controller-debug.cpp \
--- /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/grid-impl.h>
+
+//EXTERNAL HEADERS
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/extents.h>
+#include <dali/public-api/actors/actor.h>
+
+//INTERNAL HEADERS
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-length.h>
+#include <dali-toolkit/internal/layouting/grid-locations.h>
+
+#if defined(DEBUG_ENABLED)
+static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_LAYOUT" );
+#endif
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+GridPtr Grid::New()
+{
+ GridPtr layout( new Grid() );
+ return layout;
+}
+
+Grid::Grid()
+: LayoutGroup(),
+ mTotalHeight( 0 ),
+ mTotalWidth( 0 ),
+ mNumColumns( AUTO_FIT ),
+ mNumRows( AUTO_FIT ),
+ mRequestedColumnWidth( 0 ),
+ mRequestedNumColumns( AUTO_FIT )
+{
+ mLocations = GridLocations::New();
+}
+
+Grid::~Grid(){}
+
+void Grid::SetNumberOfColumns( int columns )
+{
+ mRequestedNumColumns = columns;
+ // Store value and Relayout if changed.
+ if( columns != mNumColumns )
+ {
+ mNumColumns = columns;
+ RequestLayout();
+ }
+}
+
+int Grid::GetNumberOfColumns() const
+{
+ return mNumColumns;
+}
+
+void Grid::DetermineNumberOfColumns( int availableSpace )
+{
+ if( mRequestedNumColumns == AUTO_FIT )
+ {
+ if( availableSpace > 0 )
+ {
+ // Can only calculate number of columns if a column width has been set
+ mNumColumns = ( mRequestedColumnWidth > 0 ) ? ( availableSpace / mRequestedColumnWidth ) : 1;
+ }
+ }
+}
+
+void Grid::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec )
+{
+ DALI_LOG_STREAM( gLogFilter, Debug::Verbose,
+ "Grid::OnMeasure Actor Id:" << Actor::DownCast(GetOwner()).GetId() <<
+ " Owner:" << Actor::DownCast(GetOwner()).GetName() <<
+ " MeasureSpecs( width:"<<widthMeasureSpec<<", height:"<<heightMeasureSpec );
+
+ auto gridWidthMode = widthMeasureSpec.GetMode();
+ auto gridHeightMode = heightMeasureSpec.GetMode();
+ LayoutLength widthSize = widthMeasureSpec.GetSize();
+ LayoutLength heightSize = heightMeasureSpec.GetSize();
+
+ int availableContentWidth(0);
+ int availableContentHeight(0);
+
+ LayoutLength desiredChildHeight( 0 );
+ LayoutLength desiredChildWidth( 0 );
+
+ Extents gridLayoutPadding = GetPadding();
+
+ auto childCount = GetChildCount();
+
+ // WIDTH SPECIFICATIONS
+
+ // measure first child and use it's dimensions for layout measurement
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnMeasure MeasureSpec::Mode::EXACTLY or MeasureSpec::Mode::AT_MOST \n" );
+
+ if( childCount > 0 )
+ {
+ auto childLayoutItem = GetChildAt( 0 );
+ if( childLayoutItem )
+ {
+ auto childOwner = childLayoutItem->GetOwner();
+
+ MeasureChild( childLayoutItem, widthMeasureSpec, heightMeasureSpec );
+ desiredChildHeight = childLayoutItem->GetMeasuredHeight();
+ desiredChildWidth = childLayoutItem->GetMeasuredWidth();
+
+ // If child has a margin then add it to desired size
+ Extents childMargin = childOwner.GetProperty<Extents>( Toolkit::Control::Property::MARGIN );
+ desiredChildHeight += childMargin.top + childMargin.bottom;
+ desiredChildWidth += childMargin.start + childMargin.end;
+
+ mTotalWidth = desiredChildWidth * mNumColumns;
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnMeasure TotalDesiredWidth(%d) \n", mTotalWidth.mValue );
+ } // Child is LayoutItem
+ } // Child exists
+
+ // Include padding for max and min checks
+ mTotalWidth += gridLayoutPadding.start + gridLayoutPadding.end;
+
+ // Ensure width does not exceed specified atmost width or less than mininum width
+ mTotalWidth = std::max( mTotalWidth, GetSuggestedMinimumWidth() );
+
+ // widthMode EXACTLY so grid must be the given width
+ if( gridWidthMode == MeasureSpec::Mode::EXACTLY || gridWidthMode == MeasureSpec::Mode::AT_MOST )
+ {
+ // In the case of AT_MOST, widthSize is the max limit.
+ mTotalWidth = std::min( mTotalWidth, widthSize );
+ }
+
+ availableContentWidth = mTotalWidth - gridLayoutPadding.start - gridLayoutPadding.end;
+ widthSize = mTotalWidth;
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnMeasure availableContentWidth(%d) mTotalWidth(%d) \n",
+ availableContentWidth,
+ mTotalWidth.mValue );
+ // HEIGHT SPECIFICATIONS
+
+ // heightMode EXACTLY so grid must be the given height
+ if( gridHeightMode == MeasureSpec::Mode::EXACTLY || gridHeightMode == MeasureSpec::Mode::AT_MOST )
+ {
+ if( childCount > 0 )
+ {
+ mTotalHeight = gridLayoutPadding.top + gridLayoutPadding.bottom;
+
+ for( auto i = 0u; i < childCount; i += mNumColumns )
+ {
+ mTotalHeight += desiredChildHeight;
+ }
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnMeasure TotalDesiredHeight(%d) \n",
+ mTotalHeight.mValue );
+
+ // Ensure ourHeight does not exceed specified atmost height
+ mTotalHeight = std::min( mTotalHeight, heightSize );
+ mTotalHeight = std::max( mTotalHeight, GetSuggestedMinimumHeight() );
+
+ heightSize = mTotalHeight;
+ } // Child exists
+
+ // In the case of AT_MOST, availableContentHeigth is the max limit.
+ availableContentHeight = heightSize - gridLayoutPadding.top - gridLayoutPadding.bottom;
+ }
+ else
+ {
+ // Grid expands to fit content
+
+ // If number of columns AUTO_FIT then set to 1 column.
+
+ // Calculate numbers of rows, round down result as later check for remainder.
+ mNumRows = childCount / ( ( mNumColumns ) ? mNumColumns : 1 );
+ // If number of cells not cleanly dividable by colums, add another row to house remainder cells.
+ mNumRows += ( childCount % ( ( mNumColumns ) ? mNumColumns : 1 ) ) ? 1 : 0;
+
+ availableContentHeight = desiredChildHeight * mNumRows;
+ }
+
+ // If number of columns not defined
+ DetermineNumberOfColumns( availableContentWidth );
+
+ // Locations define the start, end,top and bottom of each cell.
+ mLocations->CalculateLocations( mNumColumns, availableContentWidth, availableContentHeight, childCount, 0, 0 );
+
+
+ SetMeasuredDimensions( ResolveSizeAndState( widthSize, widthMeasureSpec, MeasuredSize::State::MEASURED_SIZE_OK ),
+ ResolveSizeAndState( heightSize, heightMeasureSpec, MeasuredSize::State::MEASURED_SIZE_OK ) );
+}
+
+void Grid::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
+{
+ auto owner = GetOwner();
+ auto actor = Actor::DownCast(owner);
+ auto count = GetChildCount();
+
+ GridLocations::LocationVector locations = mLocations->GetLocations();
+
+ Extents gridLayoutPadding = GetPadding();
+ Extents childMargins;
+
+ // Margin for all children dependant on if set on first child
+ if( count )
+ {
+ LayoutItemPtr childLayout = GetChildAt( 0 );
+ if( childLayout )
+ {
+ auto childOwner = childLayout->GetOwner();
+ if( childOwner )
+ {
+ childMargins = childOwner.GetProperty<Extents>( Toolkit::Control::Property::MARGIN );
+ }
+ }
+ }
+
+ for( unsigned int i = 0; i < count; i++)
+ {
+ // for each child
+ int childIndex = i;
+ LayoutItemPtr childLayout = GetChildAt( childIndex );
+ if( childLayout != nullptr )
+ {
+ // Get start and end position of child x1,x2
+ auto x1 = locations[ i ].xStart;
+ auto x2 = locations[ i ].xEnd;
+
+ // Get top and bottom position of child y1,y2
+ auto y1 = locations[ i ].yTop;
+ auto y2 = locations[ i ].yBottom;
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnLayout cellSize(%d,%d) \n", x2 - x1, y2 - y1);
+
+ // Offset children by the grids padding if present
+ x1 += gridLayoutPadding.start;
+ x2 += gridLayoutPadding.start;
+ y1 += gridLayoutPadding.top;
+ y2 += gridLayoutPadding.top;
+
+ // Offset children by the margin of the first child ( if required ).
+ x1 += childMargins.start;
+ x2 -= childMargins.end;
+ y1 += childMargins.top;
+ y2 -= childMargins.bottom;
+
+ childLayout->Layout( x1, y1, x2, y2 );
+ }
+ }
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_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/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL_HEADERS
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/devel-api/layouting/grid.h>
+#include <dali-toolkit/internal/layouting/grid-locations.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+class Grid;
+using GridPtr = IntrusivePtr<Grid>;
+
+class Grid final : public LayoutGroup
+{
+public:
+
+ /**
+ * Creates a pointer to an Internal Grid
+ */
+ static GridPtr New();
+
+ /**
+ * Set grid's the number of columns
+ * @param[in] columns number of columns
+ */
+ void SetNumberOfColumns( int columns );
+
+ /**
+ * Get number of columns, -1 would indicate AUTO_FIT
+ * which means the number has not been set but will be calculated.
+ * @return the number of columns set
+ */
+ int GetNumberOfColumns() const;
+
+ // Movable but not copyable
+ Grid( const Grid& other ) = delete;
+ Grid& operator=( const Grid& other ) = delete;
+ Grid( Grid && ) = default;
+ Grid& operator=( Grid && ) = default;
+
+protected:
+
+ /**
+ * Default Constructor
+ */
+ Grid();
+
+ /**
+ * Destructor
+ */
+ ~Grid();
+
+ /**
+ * @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:
+
+ /**
+ * @brief
+ * For the given availableSpace, calculate or retreive the number of required columns.
+ * @param[in] availableSpace the space available for a child in each column.
+ */
+ void DetermineNumberOfColumns( int availableSpace );
+
+private:
+
+ GridLocationsPtr mLocations;
+
+ LayoutLength mTotalHeight;
+ LayoutLength mTotalWidth;
+
+ const int AUTO_FIT = -1;
+
+ int mNumColumns;
+ int mNumRows;
+
+ int mHorizontalSpacing = 0;
+ int mVerticalSpacing = 0;
+ int mRequestedHorizontalSpacing;
+ int mRequestedColumnWidth;
+ int mRequestedNumColumns;
+ int mRequestedNumRows;
+};
+
+} // namespace Internal
+
+inline Internal::Grid& GetImplementation( Dali::Toolkit::Grid& handle )
+{
+ DALI_ASSERT_ALWAYS( handle && "Grid handle is empty" );
+ BaseObject& object = handle.GetBaseObject();
+ return static_cast<Internal::Grid&>( object );
+}
+
+inline const Internal::Grid& GetImplementation( const Dali::Toolkit::Grid& handle )
+{
+ DALI_ASSERT_ALWAYS( handle && "Grid handle is empty" );
+ const BaseObject& object = handle.GetBaseObject();
+ return static_cast<const Internal::Grid&>( object );
+}
+
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_LAYOUTINGInner
\ No newline at end of file
--- /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/grid-locations.h>
+
+// EXTERNAL HEADERS
+#include <dali/integration-api/debug.h>
+
+// INTERNAL HEADERS
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
+
+namespace
+{
+
+#if defined(DEBUG_ENABLED)
+static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_AXIS" );
+#endif
+
+}
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+GridLocationsPtr GridLocations::New()
+{
+ GridLocationsPtr gridAxis( new GridLocations() );
+ return gridAxis;
+}
+
+GridLocations::GridLocations()
+: mLocations()
+{
+}
+
+GridLocations::~GridLocations(){}
+
+void GridLocations::CalculateLocations( int numberOfColumns,
+ unsigned int availableWidth,
+ unsigned int availableHeight,
+ unsigned int numberOfCells,
+ unsigned int columnWidth,
+ unsigned int rowHeight )
+{
+ mLocations.clear();
+
+ // Calculate width and height of columns and rows.
+
+ // Calculate numbers of rows, round down result as later check for remainder.
+ unsigned int numberOfRows = numberOfCells/numberOfColumns;
+ // If number of cells not cleanly dividable by colums, add another row to house remainder cells.
+ numberOfRows += (numberOfCells%numberOfColumns)?1:0;
+
+ unsigned int maxColumnWidth = availableWidth / numberOfColumns;
+
+ if( columnWidth > 0 )
+ {
+ // Column width supplied so use this unless exceeds available width.
+ columnWidth = std::min( columnWidth, maxColumnWidth );
+ }
+ else
+ {
+ // Column width not supplied so use calculated value
+ columnWidth = maxColumnWidth;
+ }
+
+ unsigned int maxRowHeight = availableHeight / numberOfRows;
+
+ if( rowHeight > 0 )
+ {
+ // Column height supplied so use this unless exceeds available height.
+ rowHeight = std::min( rowHeight, maxRowHeight );
+ }
+ else
+ {
+ // Column height not supplied so use calculated value
+ rowHeight = maxRowHeight;
+ }
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ColumWidth[%d] RowHeight[%d] NumberOfRows[%d] NumberOfColumns[%d]\n",
+ columnWidth, rowHeight, numberOfRows, numberOfColumns );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Remainder[%d]\n", numberOfCells%numberOfColumns );
+
+ int y1 = 0;
+ int y2 = y1 + rowHeight;
+
+ // Calculate start, end, top and bottom coordinate of each cell.
+
+ // Iterate rows
+ for( auto i = 0u; i < numberOfRows; i++ )
+ {
+ int x1 = 0;
+ int x2 = x1 + columnWidth;
+
+ // Iterate columns
+ for( auto j = 0; j < numberOfColumns; j++ )
+ {
+ GridLocations::Cell cell( x1, x2, y1, y2 );
+ mLocations.push_back( cell );
+ // Calculate starting x and ending x position of each column
+ x1 = x2;
+ x2 = x2 + columnWidth;
+ }
+
+ // Calculate top y and bottom y position of each row.
+ y1 = y2;
+ y2 = y2 + rowHeight;
+ }
+
+#if defined(DEBUG_ENABLED)
+ std::ostringstream oss;
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GridLocations::CalculateLocations (%d)\n", numberOfCells );
+ for( auto i = 0u; i < numberOfCells; i++ )
+ {
+ DALI_LOG_STREAM( gLogFilter, Debug::Verbose,"x1:"<<mLocations[i].xStart<<" x2:"<<mLocations[i].xEnd<<" y1:"<<mLocations[i].yTop<<" y2:"<<mLocations[i].yBottom);
+ }
+#endif
+}
+
+GridLocations::LocationVector GridLocations::GetLocations()
+{
+#if defined(DEBUG_ENABLED)
+ std::ostringstream oss;
+ auto itemCount = mLocations.size(); // mVerticalLocations mirrors this so same size.
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GridLocations::GetLocations for %u cells\n", itemCount );
+ for( auto i = 0u; i < itemCount; i++ )
+ {
+ DALI_LOG_STREAM( gLogFilter, Debug::Verbose,"x1:"<<mLocations[i].xStart<<" x2:"<<mLocations[i].xEnd<<" y1:"<<mLocations[i].yTop<<" y2:"<<mLocations[i].yBottom);
+ }
+#endif
+
+ return mLocations;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_LOCATIONS_H
+#define DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_LOCATIONS_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/common/intrusive-ptr.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/object/ref-object.h>
+#include <limits.h>
+
+// INTERNAL HEADERS
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+class GridLocations;
+using GridLocationsPtr = IntrusivePtr<GridLocations>;
+
+/* @brief This internal class houses the algorithm for computing the locations and size of cells.
+ *
+ * A Grid layout uses two instances of this class
+ * distinguished by the "horizontal" flag which is true for the horizontal axis and false
+ * for the vertical one.
+ */
+
+class GridLocations : public RefObject
+{
+
+public:
+
+ static const int UNDEFINED = INT_MIN;
+
+ static const unsigned int HORIZONTAL = 0;
+ static const unsigned int VERTICAL = 1;
+
+ struct Cell
+ {
+ int xStart;
+ int xEnd;
+ int yTop;
+ int yBottom;
+ int explictlyDefined;
+
+ Cell( int x1, int x2, int y1, int y2): xStart(x1), xEnd(x2), yTop(y1), yBottom(y2){};
+ };
+
+ typedef std::vector< Cell > LocationVector;
+
+public:
+
+ static GridLocationsPtr New();
+
+ /*
+ * Uses the given parameters to calculate the x,y coordinates of each cell and cell size.
+ */
+ void CalculateLocations( int numberOfColumns, unsigned int availableWidth,
+ unsigned int availableHeight, unsigned int numberOfCells,
+ unsigned int columnWidth, unsigned int rowHeight );
+
+ LocationVector GetLocations();
+
+private:
+
+ GridLocations();
+ ~GridLocations();
+ GridLocations( const GridLocations& other ) = delete;
+ GridLocations& operator=( const GridLocations& other ) = delete;
+
+private:
+
+ LocationVector mLocations;
+
+};
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_LOCATIONS_H
\ No newline at end of file