2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/controls/table-view/table-view-impl.h>
23 #include <dali/public-api/object/ref-object.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/object/type-registry-helper.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/devel-api/scripting/scripting.h>
28 #include <dali/public-api/size-negotiation/relayout-container.h>
29 #include <dali/integration-api/debug.h>
36 * @brief Should the tableview fit around the given actor
38 * @param[in] actor The child actor to test against
39 * @param[dimension] The dimension to test against
41 bool FitToChild( Actor actor, Dimension::Type dimension )
43 return actor.GetResizePolicy( dimension ) != ResizePolicy::FILL_TO_PARENT && actor.GetRelayoutSize( dimension ) > 0.0f;
46 #if defined(DEBUG_ENABLED)
47 // debugging support, very useful when new features are added or bugs are hunted down
48 // currently not called from code so compiler will optimize these away, kept here for future debugging
50 #define TABLEVIEW_TAG "DALI Toolkit::TableView "
51 #define TV_LOG(fmt, args...) Debug::LogMessage(Debug::DebugInfo, TABLEVIEW_TAG fmt, ## args)
52 //#define TABLEVIEW_DEBUG 1
54 #if defined(TABLEVIEW_DEBUG)
55 void PrintArray( Array2d<Dali::Toolkit::Internal::TableView::CellData>& array )
57 TV_LOG( "Array2d<CellData> size [%d,%d] \n", array.GetRows(), array.GetColumns() );
59 for( unsigned int i = 0; i < array.GetRows(); ++i )
61 for( unsigned int j = 0; j < array.GetColumns(); ++j )
63 Dali::Toolkit::Internal::TableView::CellData data = array[i][j];
65 std::string actorName;
69 actorName = data.actor.GetName();
71 TV_LOG("Array[%d,%d]=%c %s %d,%d,%d,%d ", i, j, actor, actorName.c_str(),
72 data.position.rowIndex, data.position.columnIndex,
73 data.position.rowSpan, data.position.columnSpan );
79 // debugging support, very useful when new features are added or bugs are hunted down
80 // currently not called from code so compiler will optimize these away, kept here for future debugging
81 void PrintArray( Array2d<Size>& array )
83 TV_LOG( "Array2d<Size> size [%d,%d] \n", array.GetRows(), array.GetColumns() );
85 for( unsigned int i = 0; i < array.GetRows(); ++i )
87 for( unsigned int j = 0; j < array.GetColumns(); ++j )
89 TV_LOG( "Array[%d,%d]=%.2f,%.2f ", i, j, array[i][j].width, array[i][j].height );
94 // debugging support, very useful when new features are added or bugs are hunted down
95 // currently not called from code so compiler will optimize these away, kept here for future debugging
96 void PrintVector( std::vector<float>& array )
98 TV_LOG( "vector, size [%d]\n", array.size() );
100 for( unsigned int i = 0; i < array.size(); ++i )
102 TV_LOG( "vector[%d]=%.2f ", i, array[i] );
106 #endif // defined(TABLEVIEW_DEBUG)
107 #endif // defined(DEBUG_ENABLED)
126 return Toolkit::TableView::New( 0, 0 );
129 // Setup properties, signals and actions using the type-registry.
130 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TableView, Toolkit::Control, Create );
132 DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "rows", INTEGER, ROWS )
133 DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "columns", INTEGER, COLUMNS )
134 DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "cellPadding", VECTOR2, CELL_PADDING )
135 DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "layoutRows", MAP, LAYOUT_ROWS )
136 DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "layoutColumns", MAP, LAYOUT_COLUMNS )
137 DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellIndex", VECTOR2, CELL_INDEX )
138 DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "rowSpan", FLOAT, ROW_SPAN )
139 DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "columnSpan", FLOAT, COLUMN_SPAN )
140 DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellHorizontalAlignment", STRING, CELL_HORIZONTAL_ALIGNMENT )
141 DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellVerticalAlignment", STRING, CELL_VERTICAL_ALIGNMENT )
143 DALI_TYPE_REGISTRATION_END()
145 const Scripting::StringEnum LAYOUT_POLICY_STRING_TABLE[] =
147 { "fixed", Toolkit::TableView::FIXED },
148 { "relative", Toolkit::TableView::RELATIVE },
149 { "fill", Toolkit::TableView::FILL },
150 { "fit", Toolkit::TableView::FIT }
152 const unsigned int LAYOUT_POLICY_STRING_TABLE_COUNT = sizeof(LAYOUT_POLICY_STRING_TABLE) / sizeof( LAYOUT_POLICY_STRING_TABLE[0] );
154 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
156 {"left", HorizontalAlignment::LEFT},
157 {"center", HorizontalAlignment::CENTER},
158 {"right", HorizontalAlignment::RIGHT}
160 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof(HORIZONTAL_ALIGNMENT_STRING_TABLE) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
162 const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
164 {"top", VerticalAlignment::TOP},
165 {"center", VerticalAlignment::CENTER},
166 {"bottom", VerticalAlignment::BOTTOM}
168 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof(VERTICAL_ALIGNMENT_STRING_TABLE) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
170 } // Unnamed namespace
172 Toolkit::TableView TableView::New( unsigned int initialRows, unsigned int initialColumns )
174 // Create the implementation, temporarily owned by this handle on stack
175 IntrusivePtr< TableView > impl = new TableView( initialRows, initialColumns );
177 // Pass ownership to CustomActor handle
178 Toolkit::TableView handle( *impl );
180 // Second-phase init of the implementation
181 // This can only be done after the CustomActor connection has been made...
187 bool TableView::AddChild( Actor& child, const Toolkit::TableView::CellPosition& position )
189 // check that the child is valid
190 DALI_ASSERT_ALWAYS( child );
192 // if child is already parented, we adopt it
195 // check if we need to expand our data array
196 if( position.rowIndex >= mCellData.GetRows() )
198 // only adding new rows
199 ResizeContainers( position.rowIndex + 1, mCellData.GetColumns() );
202 if( position.columnIndex >= mCellData.GetColumns() )
204 // only adding new columns
205 ResizeContainers( mCellData.GetRows(), position.columnIndex + 1 );
208 // check if there already is something in this cell
209 if( mCellData[ position.rowIndex ][ position.columnIndex ].actor )
211 return false; // cannot share a cell, it would complicate all logic and not bring much benefit
214 RelayoutingLock lock( *this );
218 // if child spans multiple rows of columns
219 if( ( position.rowSpan > 1 ) && ( position.rowIndex + position.rowSpan > mCellData.GetRows() ) )
221 // increase table size for the full span, only increasing rows
222 ResizeContainers( position.rowIndex + position.rowSpan, mCellData.GetColumns() );
225 if( ( position.columnSpan > 1 ) && ( position.columnIndex + position.columnSpan > mCellData.GetColumns() ) )
227 // increase table size for the full span, only increasing columns
228 ResizeContainers( mCellData.GetRows(), position.columnIndex + position.columnSpan );
231 // Fill in all cells that need the data
234 data.position = position;
236 for( unsigned int row = position.rowIndex; row < ( position.rowIndex + position.rowSpan ); ++row )
238 // store same information to all cells, this way we can identify
239 // if a cell is the prime location of an actor or a spanned one
240 for( unsigned int column = position.columnIndex; column < ( position.columnIndex + position.columnSpan ); ++column )
242 // store same information to all cells, this way we can identify
243 // if a cell is the prime location of an actor or a spanned one
244 mCellData[ row ][ column ] = data;
248 // Relayout the whole table
249 if( mRowData[position.rowIndex].sizePolicy == Toolkit::TableView::FIT && position.rowSpan == 1 )
253 if( mColumnData[position.columnIndex].sizePolicy == Toolkit::TableView::FIT && position.columnSpan == 1 )
260 return true; // Addition successful
263 Actor TableView::GetChildAt( const Toolkit::TableView::CellPosition& position )
265 if( ( position.rowIndex < mCellData.GetRows() ) && ( position.columnIndex < mCellData.GetColumns() ) )
267 return mCellData[ position.rowIndex ][ position.columnIndex ].actor;
270 // Return an empty handle
274 Actor TableView::RemoveChildAt( const Toolkit::TableView::CellPosition& position )
276 // get the child handle
277 Actor child = GetChildAt( position );
278 // if no real actor there, nothing else to be done
281 RelayoutingLock lock( *this );
282 // Remove the child, this will trigger a call to OnChildRemove
283 Self().Remove( child );
285 // relayout the table only if instances were found
286 if( RemoveAllInstances( child ) )
288 if( mRowData[position.rowIndex].sizePolicy == Toolkit::TableView::FIT )
292 if( mColumnData[position.columnIndex].sizePolicy == Toolkit::TableView::FIT )
299 // return the child back to caller
303 bool TableView::FindChildPosition( const Actor& child, Toolkit::TableView::CellPosition& positionOut )
305 // Only find valid child actors
308 // Walk through the layout data
309 const unsigned int rowCount = mCellData.GetRows();
310 const unsigned int columnCount = mCellData.GetColumns();
312 for( unsigned int row = 0; row < rowCount; ++row )
314 for( unsigned int column = 0; column < columnCount; ++column )
316 if( mCellData[ row ][ column ].actor == child )
318 positionOut = mCellData[ row ][ column ].position;
328 void TableView::InsertRow( unsigned int rowIndex )
330 RelayoutingLock lock( *this );
332 mCellData.InsertRow( rowIndex );
334 // Need to update the cell infos for the items that moved
335 const unsigned int rowCount = mCellData.GetRows();
336 const unsigned int columnCount = mCellData.GetColumns();
338 for( unsigned int row = 0; row < rowCount; ++row )
340 for( unsigned int column = 0; column < columnCount; ++column )
342 Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
344 // If cell is spanning and above and spans to inserted row
345 if( ( position.rowSpan > 1 ) && ( position.rowIndex <= rowIndex ) &&
346 ( position.rowIndex + position.rowSpan > rowIndex ) )
351 // Copy cell to occupy the new column
352 mCellData[ rowIndex ][ column ] = mCellData[ row ][ column ];
354 else if( row > rowIndex ) // If below of inserted row, increase row index
362 // Expand row data array
363 mRowData.Insert( mRowData.Begin() + rowIndex, RowColumnData() );
365 // Sizes may have changed, so relayout
370 void TableView::DeleteRow( unsigned int rowIndex )
372 std::vector< Actor > ignored;
373 DeleteRow( rowIndex, ignored );
376 void TableView::DeleteRow( unsigned int rowIndex, std::vector<Actor>& removed )
378 RelayoutingLock lock( *this );
381 std::vector< CellData > lost;
382 mCellData.DeleteRow( rowIndex, lost );
384 // Need to update the cell infos for the items that moved
385 const unsigned int rowCount = mCellData.GetRows();
386 const unsigned int columnCount = mCellData.GetColumns();
388 for( unsigned int row = 0; row < rowCount; ++row )
390 for( unsigned int column = 0; column < columnCount; ++column )
392 Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
394 // If cell is spanning and above and spans to deleted row
395 if( ( position.rowSpan > 1 ) && ( position.rowIndex <= rowIndex ) &&
396 ( position.rowIndex + position.rowSpan > rowIndex ) )
399 if( position.rowSpan > 1 )
404 else if( row >= rowIndex ) // If below of or at the inserted row, decrease row index
407 if( position.rowIndex > 0 )
415 // 1 row removed, 0 columns
416 RemoveAndGetLostActors( lost, removed, 1u, 0u );
418 // Contract row data array
419 mRowData.Erase( mRowData.Begin() + rowIndex );
421 // Sizes may have changed, so relayout
423 // it is possible that the deletion of row leads to remove of child which might further lead to the change of FIT column
429 void TableView::InsertColumn( unsigned int columnIndex )
431 RelayoutingLock lock( *this );
433 // Insert the new column
434 mCellData.InsertColumn( columnIndex );
436 // Need to update the cell infos for the items that moved
437 const unsigned int rowCount = mCellData.GetRows();
438 const unsigned int columnCount = mCellData.GetColumns();
440 for( unsigned int row = 0; row < rowCount; ++row )
442 for( unsigned int column = 0; column < columnCount; ++column )
444 Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
446 // If cell is spanning and left side and spans to inserted column
447 if( ( position.columnSpan > 1 ) && ( position.columnIndex <= columnIndex ) &&
448 ( position.columnIndex + position.columnSpan > columnIndex ) )
451 position.columnSpan++;
453 // Copy cell to occupy the new column
454 mCellData[ row ][ columnIndex ] = mCellData[ row ][ column ];
456 else if( column > columnIndex ) // If on the right side of inserted column, increase column index
459 position.columnIndex++;
464 // Expand column data array
465 mColumnData.Insert( mColumnData.Begin() + columnIndex, RowColumnData() );
467 // Sizes may have changed so relayout
472 void TableView::DeleteColumn( unsigned int columnIndex )
474 std::vector< Actor > ignored;
475 DeleteColumn( columnIndex, ignored );
478 void TableView::DeleteColumn( unsigned int columnIndex, std::vector<Actor>& removed )
480 RelayoutingLock lock( *this );
483 std::vector< CellData > lost;
484 mCellData.DeleteColumn( columnIndex, lost );
486 // Need to update the cell infos for the items that moved
487 const unsigned int rowCount = mCellData.GetRows();
488 const unsigned int columnCount = mCellData.GetColumns();
490 for( unsigned int row = 0; row < rowCount; ++row )
492 for( unsigned int column = 0; column < columnCount; ++column )
494 Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
496 // If cell is spanning and left side and spans to inserted column
497 if( ( position.columnSpan > 1 ) && ( position.columnIndex <= columnIndex ) &&
498 ( position.columnIndex + position.columnSpan > columnIndex ) )
501 if( position.columnSpan > 1 )
503 position.columnSpan--;
506 else if( column >= columnIndex ) // If on the right side of or at the inserted column, decrease column index
509 if( position.columnIndex > 0 )
511 position.columnIndex--;
517 // 0 rows, 1 column removed
518 RemoveAndGetLostActors( lost, removed, 0u, 1u );
520 // Contract column data array
521 mColumnData.Erase( mColumnData.Begin() + columnIndex );
523 // Size may have changed so relayout
525 // it is possible that the deletion of column leads to remove of child which might further lead to the change of FIT row
531 void TableView::Resize( unsigned int rows, unsigned int columns )
533 std::vector< Actor > ignored;
534 Resize( rows, columns, ignored );
537 void TableView::Resize( unsigned int rows, unsigned int columns, std::vector<Actor>& removed )
539 RelayoutingLock lock( *this );
541 unsigned int oldRows = GetRows();
542 unsigned int oldColumns = GetColumns();
545 std::vector< CellData > lost;
546 ResizeContainers( rows, columns, lost );
548 // Calculate if we lost rows
549 unsigned int rowsRemoved = 0;
550 unsigned int newRows = GetRows();
552 if( oldRows < newRows )
554 rowsRemoved = newRows - oldRows;
557 // Calculate if we lost columns
558 unsigned int columnsRemoved = 0;
559 unsigned int newColumns = GetColumns();
560 if( oldColumns < newColumns )
562 rowsRemoved = newColumns - oldColumns;
565 RemoveAndGetLostActors( lost, removed, rowsRemoved, columnsRemoved );
567 // Sizes may have changed so request a relayout
573 void TableView::SetCellPadding( Size padding )
575 // If padding really changed
576 if( padding != mPadding )
584 Size TableView::GetCellPadding()
589 void TableView::SetFitHeight( unsigned int rowIndex )
591 DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
593 if( mRowData[ rowIndex ].sizePolicy != Toolkit::TableView::FIT )
595 mRowData[ rowIndex ].sizePolicy = Toolkit::TableView::FIT;
602 bool TableView::IsFitHeight( unsigned int rowIndex ) const
604 DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
606 return mRowData[ rowIndex ].sizePolicy == Toolkit::TableView::FIT;
609 void TableView::SetFitWidth( unsigned int columnIndex )
611 DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
613 if( mColumnData[ columnIndex ].sizePolicy != Toolkit::TableView::FIT )
615 mColumnData[ columnIndex ].sizePolicy = Toolkit::TableView::FIT;
622 bool TableView::IsFitWidth( unsigned int columnIndex ) const
624 DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
626 return mColumnData[ columnIndex ].sizePolicy == Toolkit::TableView::FIT;
629 void TableView::SetFixedHeight( unsigned int rowIndex, float height )
631 DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
633 RowColumnData& data = mRowData[ rowIndex ];
635 data.sizePolicy = Toolkit::TableView::FIXED;
641 float TableView::GetFixedHeight( unsigned int rowIndex ) const
643 DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
645 return mRowData[ rowIndex ].size;
648 void TableView::SetFixedWidth( unsigned int columnIndex, float width )
650 DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
652 RowColumnData& data = mColumnData[ columnIndex ];
654 data.sizePolicy = Toolkit::TableView::FIXED;
660 float TableView::GetFixedWidth( unsigned int columnIndex ) const
662 DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
664 return mColumnData[ columnIndex ].size;
667 void TableView::SetRelativeHeight( unsigned int rowIndex, float heightPercentage )
669 DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
671 RowColumnData& data = mRowData[ rowIndex ];
672 data.fillRatio = heightPercentage;
673 data.sizePolicy = Toolkit::TableView::RELATIVE;
679 float TableView::GetRelativeHeight( unsigned int rowIndex ) const
681 DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
683 return mRowData[ rowIndex ].fillRatio;
686 void TableView::SetRelativeWidth( unsigned int columnIndex, float widthPercentage )
688 DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
690 RowColumnData& data = mColumnData[ columnIndex ];
691 data.fillRatio = widthPercentage;
692 data.sizePolicy = Toolkit::TableView::RELATIVE;
698 float TableView::GetRelativeWidth( unsigned int columnIndex ) const
700 DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
702 return mColumnData[ columnIndex ].fillRatio;
705 void TableView::OnCalculateRelayoutSize( Dimension::Type dimension )
707 if( (dimension & Dimension::WIDTH) && mColumnDirty )
710 * FIXED and FIT have size in pixel
711 * Nothing to do with FIXED, as its value is assigned by user and will not get changed
713 * Need to update the size for FIT column here
715 CalculateFitSizes( mColumnData, Dimension::WIDTH );
717 /* RELATIVE and FILL have size in ratio
718 * Their size in pixel is not available until we get the negotiated size for the whole table
719 * Nothing to do with RELATIVE, as its ratio is assigned by user and will not get changed
721 * Need to update the ratio for FILL column here
723 CalculateFillSizes( mColumnData );
725 mFixedTotals.width = CalculateTotalFixedSize( mColumnData );
728 if( (dimension & Dimension::HEIGHT) && mRowDirty )
730 // refer to the comment above
731 CalculateFitSizes( mRowData, Dimension::HEIGHT );
733 // refer to the comment above
734 CalculateFillSizes( mRowData );
736 mFixedTotals.height = CalculateTotalFixedSize( mRowData );
740 void TableView::OnLayoutNegotiated( float size, Dimension::Type dimension )
742 // Update the column sizes
743 if( (dimension & Dimension::WIDTH) && mColumnDirty )
745 float remainingSize = size - mFixedTotals.width;
746 if( remainingSize < 0.0f )
748 remainingSize = 0.0f;
751 // update every column position in ColumnData array
752 float cumulatedWidth = 0.0f;
753 for( unsigned int column = 0, columnCount = mCellData.GetColumns(); column < columnCount; ++column )
755 if( mColumnData[ column ].sizePolicy == Toolkit::TableView::FILL || mColumnData[ column ].sizePolicy == Toolkit::TableView::RELATIVE)
757 mColumnData[ column ].size = mColumnData[ column ].fillRatio * remainingSize;
760 cumulatedWidth += mColumnData[ column ].size;
761 mColumnData[column].position = cumulatedWidth;
764 mColumnDirty = false;
767 // Update the row sizes
768 if( (dimension & Dimension::HEIGHT) && mRowDirty )
770 float remainingSize = size - mFixedTotals.height;
771 if( remainingSize < 0.0f )
773 remainingSize = 0.0f;
776 // update every row position in RowData array
777 float cumulatedHeight = 0.0f;
778 for( unsigned int row = 0, rowCount = mCellData.GetRows(); row < rowCount; ++row )
780 if( mRowData[ row ].sizePolicy == Toolkit::TableView::FILL || mRowData[ row ].sizePolicy == Toolkit::TableView::RELATIVE)
782 mRowData[ row ].size = mRowData[ row ].fillRatio * remainingSize;
785 cumulatedHeight += mRowData[ row ].size;
786 mRowData[row].position = cumulatedHeight;
793 void TableView::OnSizeSet( const Vector3& size )
795 // If this table view is size negotiated by another actor or control, then the
796 // rows and columns must be recalculated or the new size will not take effect.
797 mRowDirty = mColumnDirty = true;
800 Control::OnSizeSet( size );
803 void TableView::OnRelayout( const Vector2& size, RelayoutContainer& container )
805 // Go through the layout data
806 for( unsigned int row = 0, rowCount = mCellData.GetRows(); row < rowCount; ++row )
808 for( unsigned int column = 0, columnCount = mCellData.GetColumns(); column < columnCount; ++column )
810 CellData& cellData= mCellData[ row ][ column ];
811 Actor& actor = cellData.actor;
812 const Toolkit::TableView::CellPosition position = cellData.position;
814 // If there is an actor and this is the main cell of the actor.
815 // An actor can be in multiple cells if its row or column span is more than 1.
816 // We however must lay out each actor only once.
817 if( actor && position.rowIndex == row && position.columnIndex == column )
819 // Anchor actor to top left of the cell
820 if( actor.GetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >() )
822 actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
824 actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
827 actor.GetPadding( padding );
829 float left = column > 0 ? mColumnData[column-1].position : 0.f;
830 float right = mColumnData[column+position.columnSpan-1].position;
831 float top = row > 0 ? mRowData[row-1].position : 0.f;
832 float bottom = mRowData[row+position.rowSpan-1].position;
834 if( cellData.horizontalAlignment == HorizontalAlignment::LEFT )
836 actor.SetX( left + mPadding.width + padding.left );
838 else if( cellData.horizontalAlignment == HorizontalAlignment::RIGHT )
840 actor.SetX( right - mPadding.width - padding.right - actor.GetRelayoutSize( Dimension::WIDTH ) );
842 else //if( cellData.horizontalAlignment == HorizontalAlignment::CENTER )
844 actor.SetX( (left + right + padding.left - padding.right - actor.GetRelayoutSize( Dimension::WIDTH )) * 0.5f );
847 if( cellData.verticalAlignment == VerticalAlignment::TOP )
849 actor.SetY( top + mPadding.height + padding.top );
851 else if( cellData.verticalAlignment == VerticalAlignment::BOTTOM )
853 actor.SetY( bottom - mPadding.height - padding.bottom - actor.GetRelayoutSize( Dimension::HEIGHT ) );
855 else //if( cellData.verticalAlignment = VerticalAlignment::CENTER )
857 actor.SetY( (top + bottom + padding.top - padding.bottom - actor.GetRelayoutSize( Dimension::HEIGHT )) * 0.5f );
864 unsigned int TableView::GetRows()
866 return mCellData.GetRows();
869 unsigned int TableView::GetColumns()
871 return mCellData.GetColumns();
874 void TableView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
876 Toolkit::TableView tableView = Toolkit::TableView::DownCast( Dali::BaseHandle( object ) );
880 TableView& tableViewImpl( GetImpl( tableView ) );
883 case Toolkit::TableView::Property::ROWS:
886 if( value.Get( rows ) && rows >= 0 )
888 if( static_cast<unsigned int>(rows) != tableViewImpl.GetRows() )
890 tableViewImpl.Resize( rows, tableViewImpl.GetColumns() );
895 case Toolkit::TableView::Property::COLUMNS:
898 if( value.Get( columns ) && columns >= 0 )
900 if( static_cast<unsigned int>( columns ) != tableViewImpl.GetColumns() )
902 tableViewImpl.Resize( tableViewImpl.GetRows(), value.Get<int>() );
907 case Toolkit::TableView::Property::CELL_PADDING:
909 tableViewImpl.SetCellPadding( value.Get<Vector2>() );
912 case Toolkit::TableView::Property::LAYOUT_ROWS:
914 SetHeightOrWidthProperty( tableViewImpl, &TableView::SetFixedHeight, &TableView::SetRelativeHeight, &TableView::SetFitHeight, value );
917 case Toolkit::TableView::Property::LAYOUT_COLUMNS:
919 SetHeightOrWidthProperty( tableViewImpl, &TableView::SetFixedWidth, &TableView::SetRelativeWidth, &TableView::SetFitWidth, value );
926 Property::Value TableView::GetProperty( BaseObject* object, Property::Index index )
928 Property::Value value;
930 Toolkit::TableView tableView = Toolkit::TableView::DownCast( Dali::BaseHandle( object ) );
934 TableView& tableViewImpl( GetImpl( tableView ) );
937 case Toolkit::TableView::Property::ROWS:
939 value = static_cast<int>( tableViewImpl.GetRows() );
942 case Toolkit::TableView::Property::COLUMNS:
944 value = static_cast<int>( tableViewImpl.GetColumns() );
947 case Toolkit::TableView::Property::CELL_PADDING:
949 value = tableViewImpl.GetCellPadding();
952 case Toolkit::TableView::Property::LAYOUT_ROWS:
954 value = tableViewImpl.GetRowHeightsPropertyValue();
957 case Toolkit::TableView::Property::LAYOUT_COLUMNS:
959 value = tableViewImpl.GetColumnWidthsPropertyValue();
968 void TableView::OnChildAdd( Actor& child )
970 if( ! mLayoutingChild )
972 // Ensure we're not in the middle of laying out children
974 // Check child properties on actor to decide its position inside the table
975 HorizontalAlignment::Type horizontalAlignment = HorizontalAlignment::LEFT;
976 VerticalAlignment::Type verticalAlignment = VerticalAlignment::TOP;
978 if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ) != Property::NONE )
980 std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ).Get<std::string >();
981 Scripting::GetEnumeration< HorizontalAlignment::Type >( value.c_str(),
982 HORIZONTAL_ALIGNMENT_STRING_TABLE,
983 HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
984 horizontalAlignment );
987 if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ) != Property::NONE )
989 std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ).Get<std::string >();
990 Scripting::GetEnumeration< VerticalAlignment::Type >( value.c_str(),
991 VERTICAL_ALIGNMENT_STRING_TABLE,
992 VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
996 Toolkit::TableView::CellPosition cellPosition;
997 if( child.GetPropertyType( Toolkit::TableView::ChildProperty::ROW_SPAN ) != Property::NONE )
999 cellPosition.rowSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get<float>() );
1002 if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE )
1004 cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get<float>() );
1007 if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE )
1009 Vector2 indices = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_INDEX ).Get<Vector2 >();
1010 cellPosition.rowIndex = static_cast<unsigned int>( indices.x );
1011 cellPosition.columnIndex = static_cast<unsigned int>( indices.y );
1013 AddChild( child, cellPosition );
1014 SetCellAlignment(cellPosition, horizontalAlignment, verticalAlignment);
1018 bool availableCellFound = false;
1020 // Find the first available cell to store the actor in
1021 const unsigned int rowCount = mCellData.GetRows();
1022 const unsigned int columnCount = mCellData.GetColumns();
1023 for( unsigned int row = 0; row < rowCount && !availableCellFound; ++row )
1025 for( unsigned int column = 0; column < columnCount && !availableCellFound; ++column )
1027 if( !(mCellData[ row ][ column ].actor) )
1029 // Put the actor in the cell
1032 data.position.columnIndex = column;
1033 data.position.rowIndex = row;
1034 data.horizontalAlignment = horizontalAlignment;
1035 data.verticalAlignment = verticalAlignment;
1036 mCellData[ row ][ column ] = data;
1038 availableCellFound = true;
1044 if( ! availableCellFound )
1046 // No empty cells, so increase size of the table
1047 unsigned int newColumnCount = ( columnCount > 0 ) ? columnCount : 1;
1048 ResizeContainers( rowCount + 1, newColumnCount );
1050 // Put the actor in the first cell of the new row
1053 data.position.rowIndex = rowCount;
1054 data.position.columnIndex = 0;
1055 data.horizontalAlignment = horizontalAlignment;
1056 data.verticalAlignment = verticalAlignment;
1057 mCellData[ rowCount ][ 0 ] = data;
1064 Control::OnChildAdd( child );
1067 void TableView::OnChildRemove( Actor& child )
1069 // dont process if we're in the middle of bigger operation like delete row, column or resize
1070 if( !mLayoutingChild )
1072 // relayout the table only if instances were found
1073 if( RemoveAllInstances( child ) )
1079 Control::OnChildRemove( child );
1082 TableView::TableView( unsigned int initialRows, unsigned int initialColumns )
1083 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
1084 mCellData( initialRows, initialColumns ),
1085 mPreviousFocusedActor(),
1086 mLayoutingChild( false ),
1087 mRowDirty( true ), // Force recalculation first time
1088 mColumnDirty( true )
1090 SetKeyboardNavigationSupport( true );
1091 ResizeContainers( initialRows, initialColumns );
1094 void TableView::OnInitialize()
1096 // Make self as keyboard focusable and focus group
1097 Actor self = Self();
1098 self.SetKeyboardFocusable(true);
1099 SetAsKeyboardFocusGroup(true);
1102 void TableView::ResizeContainers( unsigned int rows, unsigned int columns )
1104 std::vector<CellData> ignored;
1105 ResizeContainers( rows, columns, ignored );
1108 void TableView::ResizeContainers( unsigned int rows, unsigned int columns, std::vector<CellData>& removed )
1111 mCellData.Resize( rows, columns, removed );
1113 // We don't care if these go smaller, data will be regenerated or is not needed anymore
1114 mRowData.Resize( rows );
1115 mColumnData.Resize( columns );
1118 void TableView::RemoveAndGetLostActors( const std::vector<CellData>& lost, std::vector<Actor>& removed,
1119 unsigned int rowsRemoved, unsigned int columnsRemoved )
1121 // iterate through all lost cells
1122 std::vector< CellData >::const_iterator iter = lost.begin();
1123 for( ; iter != lost.end(); ++iter )
1125 // if it is a valid actor
1128 // is this actor still somewhere else in the table
1129 Toolkit::TableView::CellPosition position;
1130 if( FindChildPosition( (*iter).actor, position ) )
1132 // it must be spanning multiple cells, position contains the top left most one
1133 // check if position is left of the removed location
1134 if( position.columnIndex < (*iter).position.columnIndex )
1136 // if column span is greater than 1
1137 if( mCellData[ position.rowIndex ][ position.columnIndex ].position.columnSpan > 1 )
1139 // decrease column span
1140 mCellData[ position.rowIndex ][ position.columnIndex ].position.columnSpan -= columnsRemoved;
1143 // check if position is left of the removed location
1144 if( position.rowIndex < (*iter).position.rowIndex )
1146 // if row span is greater than 1
1147 if( mCellData[ position.rowIndex ][ position.columnIndex ].position.rowSpan > 1 )
1149 // decrease row span
1150 mCellData[ position.rowIndex ][ position.columnIndex ].position.rowSpan -= rowsRemoved;
1156 // this actor is gone for good
1157 // add actor to removed container
1158 removed.push_back( (*iter).actor );
1159 // we dont want the child actor anymore
1160 Self().Remove( (*iter).actor );
1166 bool TableView::RemoveAllInstances( const Actor& child )
1169 // walk through the layout data
1170 const unsigned int rowCount = mCellData.GetRows();
1171 const unsigned int columnCount = mCellData.GetColumns();
1172 for( unsigned int row = 0; row < rowCount; ++row )
1174 for( unsigned int column = 0; column < columnCount; ++column )
1176 if( mCellData[ row ][ column ].actor == child )
1178 // clear the cell, NOTE that the cell might be spanning multiple cells
1179 mCellData[ row ][ column ] = CellData();
1187 void TableView::SetHeightOrWidthProperty(TableView& tableViewImpl,
1188 void(TableView::*funcFixed)(unsigned int, float),
1189 void(TableView::*funcRelative)(unsigned int, float),
1190 void(TableView::*funcFit)(unsigned int),
1191 const Property::Value& value )
1193 Property::Map* map = value.GetMap();
1196 unsigned int index(0);
1197 for ( unsigned int i = 0, count = map->Count(); i < count; ++i )
1199 Property::Value& item = map->GetValue(i);
1200 Property::Map* childMap = item.GetMap();
1202 std::istringstream( map->GetKey(i) ) >> index;
1205 Property::Value* policy = childMap->Find( "policy" );
1206 Property::Value* childMapValue = childMap->Find( "value" );
1207 if( policy && childMapValue )
1209 std::string policyValue;
1210 policy->Get( policyValue );
1211 Toolkit::TableView::LayoutPolicy policy;
1212 if( Scripting::GetEnumeration< Toolkit::TableView::LayoutPolicy >( policyValue.c_str(),
1213 LAYOUT_POLICY_STRING_TABLE,
1214 LAYOUT_POLICY_STRING_TABLE_COUNT,
1217 if( policy == Toolkit::TableView::FIXED )
1219 (tableViewImpl.*funcFixed)( index, childMapValue->Get<float>() );
1221 else if( policy == Toolkit::TableView::RELATIVE )
1223 (tableViewImpl.*funcRelative)( index, childMapValue->Get<float>() );
1225 else if( policy == Toolkit::TableView::FIT )
1227 (tableViewImpl.*funcFit)( index );
1229 // do nothing for FILL policy
1237 Property::Value TableView::GetRowHeightsPropertyValue()
1240 GetMapPropertyValue( mRowData, map);
1241 return Property::Value(map);
1244 Property::Value TableView::GetColumnWidthsPropertyValue()
1247 GetMapPropertyValue( mColumnData, map);
1248 return Property::Value(map);
1251 void TableView::GetMapPropertyValue( const RowColumnArray& data, Property::Map& map )
1253 const char* fixedPolicy = Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::FIXED,
1254 LAYOUT_POLICY_STRING_TABLE,
1255 LAYOUT_POLICY_STRING_TABLE_COUNT );
1256 const char* relativePolicy = Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::RELATIVE,
1257 LAYOUT_POLICY_STRING_TABLE,
1258 LAYOUT_POLICY_STRING_TABLE_COUNT );
1259 const char* fillPolicy = Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::FILL,
1260 LAYOUT_POLICY_STRING_TABLE,
1261 LAYOUT_POLICY_STRING_TABLE_COUNT );
1262 const char* fitPolicy = Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::FIT,
1263 LAYOUT_POLICY_STRING_TABLE,
1264 LAYOUT_POLICY_STRING_TABLE_COUNT );
1266 const RowColumnArray::SizeType count = data.Size();
1267 for( RowColumnArray::SizeType i = 0; i < count; i++ )
1269 const RowColumnData& dataInstance = data[ i ];
1272 switch( dataInstance.sizePolicy )
1274 case Toolkit::TableView::FIXED:
1276 item[ "policy" ] = fixedPolicy;
1277 item[ "value" ] = dataInstance.size;
1280 case Toolkit::TableView::RELATIVE:
1282 item[ "policy" ] = relativePolicy;
1283 item[ "value" ] = dataInstance.fillRatio;
1286 case Toolkit::TableView::FIT:
1288 item[ "policy" ] = fitPolicy;
1289 item[ "value" ] = 0.f;
1292 case Toolkit::TableView::FILL:
1295 item[ "policy" ] = fillPolicy;
1296 item[ "value" ] = 0.f;
1300 std::ostringstream ss;
1302 map[ ss.str() ] = item;
1306 TableView::~TableView()
1311 Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
1313 Actor nextFocusableActor;
1315 if ( !currentFocusedActor )
1317 // Nothing is currently focused, so the child in the first cell should be focused.
1318 nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
1322 Toolkit::TableView::CellPosition position;
1323 if( FindChildPosition( currentFocusedActor, position ) )
1325 // The current focused actor is a child of TableView
1326 bool focusLost = false;
1327 int currentRow = position.rowIndex;
1328 int currentColumn = position.columnIndex;
1329 int numberOfColumns = GetColumns();
1330 int numberOfRows = GetRows();
1332 bool lastCell = false;
1333 Actor nextValidActor;
1335 switch ( direction )
1337 case Toolkit::Control::KeyboardFocus::LEFT:
1341 if(--currentColumn < 0)
1343 currentColumn = numberOfColumns - 1;
1344 if(--currentRow < 0)
1347 currentRow = loopEnabled ? numberOfRows - 1 : 0;
1348 focusLost = (currentRow == 0);
1351 nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
1352 } while ( !nextValidActor && !lastCell );
1355 case Toolkit::Control::KeyboardFocus::RIGHT:
1359 if(++currentColumn > numberOfColumns - 1)
1362 if(++currentRow > numberOfRows - 1)
1365 currentRow = loopEnabled ? 0 : numberOfRows - 1;
1366 focusLost = (currentRow == numberOfRows - 1);
1369 nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
1370 } while ( !nextValidActor && !lastCell );
1373 case Toolkit::Control::KeyboardFocus::UP:
1377 if(--currentRow < 0)
1380 currentRow = loopEnabled ? numberOfRows - 1 : 0;
1381 focusLost = (currentRow == 0);
1383 nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
1384 } while ( !nextValidActor && !lastCell );
1387 case Toolkit::Control::KeyboardFocus::DOWN:
1392 if(++currentRow > numberOfRows - 1)
1395 currentRow = loopEnabled ? 0 : numberOfRows - 1;
1396 focusLost = (currentRow == numberOfRows - 1);
1398 nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
1399 } while ( !nextValidActor && !lastCell );
1408 // Move the focus if we haven't lost it.
1411 nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
1413 // Save the focused actor in the TableView.
1414 mPreviousFocusedActor = nextFocusableActor;
1419 // The current focused actor is not within this TableView.
1421 unsigned int numberOfColumns = GetColumns();
1422 unsigned int numberOfRows = GetRows();
1424 // Check whether the previous focused actor is a focus group (i.e. a layout container)
1425 bool wasFocusedOnLayoutContainer = false;
1426 Actor previousFocusedActor = mPreviousFocusedActor.GetHandle();
1427 if( previousFocusedActor )
1429 Toolkit::Control control = Toolkit::Control::DownCast( previousFocusedActor );
1432 Internal::Control& controlImpl = static_cast<Internal::Control&>(control.GetImplementation());
1433 wasFocusedOnLayoutContainer = controlImpl.IsKeyboardFocusGroup();
1437 // Check whether the previous focused actor is a layout container and also a child of this TableView
1438 Toolkit::TableView::CellPosition position;
1439 if( wasFocusedOnLayoutContainer && FindChildPosition( previousFocusedActor, position ) )
1441 nextFocusableActor = GetNextKeyboardFocusableActor(previousFocusedActor, direction, loopEnabled);
1445 // Otherwise, move the focus to either the first or the last cell according to the given direction.
1446 if(direction == Toolkit::Control::KeyboardFocus::LEFT || direction == Toolkit::Control::KeyboardFocus::UP)
1448 nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(numberOfRows - 1, numberOfColumns - 1));
1452 nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
1458 return nextFocusableActor;
1461 Vector3 TableView::GetNaturalSize()
1463 // Natural size is the size of all fixed cell widths or heights. This ignores cells with relative heights.
1464 return Vector3( mFixedTotals.width, mFixedTotals.height, 1.0f );
1467 float TableView::CalculateChildSize( const Actor& child, Dimension::Type dimension )
1469 Toolkit::TableView::CellPosition position;
1470 if( FindChildPosition( child, position) )
1474 case Dimension::WIDTH:
1476 float cellSize = 0.0f;
1477 cellSize = mColumnData[position.columnIndex+position.columnSpan-1].position
1478 - (position.columnIndex > 0 ? mColumnData[position.columnIndex-1].position : 0.f)
1479 - mPadding.width * 2.0f;
1481 if( cellSize < 0.0f )
1489 case Dimension::HEIGHT:
1491 float cellSize = 0.0f;
1493 cellSize = mRowData[position.rowIndex+position.rowSpan-1].position
1494 - (position.rowIndex > 0 ? mRowData[position.rowIndex-1].position : 0.f)
1495 - mPadding.height * 2.0f;
1497 if( cellSize < 0.0f )
1511 return 0.0f; // Child not found
1514 bool TableView::RelayoutDependentOnChildren( Dimension::Type dimension )
1516 if ( Control::RelayoutDependentOnChildren( dimension ) )
1521 return FindFit( mRowData ) || FindFit( mColumnData );
1524 void TableView::SetCellAlignment( Toolkit::TableView::CellPosition position, HorizontalAlignment::Type horizontal, VerticalAlignment::Type vertical )
1526 // Check if we need to expand our data array
1527 if( position.rowIndex >= mCellData.GetRows() )
1529 // Only adding new rows
1530 ResizeContainers( position.rowIndex + 1, mCellData.GetColumns() );
1533 if( position.columnIndex >= mCellData.GetColumns() )
1535 // Only adding new columns
1536 ResizeContainers( mCellData.GetRows(), position.columnIndex + 1 );
1539 // Set the alignment of the cell
1540 CellData& data = mCellData[ position.rowIndex ][ position.columnIndex ];
1541 data.horizontalAlignment = horizontal;
1542 data.verticalAlignment = vertical;
1545 void TableView::CalculateFillSizes( RowColumnArray& data )
1547 // First pass: Count number of fill entries and calculate used relative space
1548 Dali::Vector< RowColumnData* > fillData;
1549 float relativeTotal = 0.0f;
1551 const unsigned int dataCount = data.Size();
1553 for( unsigned int i = 0; i < dataCount; ++i )
1555 RowColumnData& dataInstance = data[ i ];
1557 if( dataInstance.sizePolicy == Toolkit::TableView::RELATIVE )
1559 relativeTotal += dataInstance.fillRatio;
1561 else if(dataInstance.sizePolicy == Toolkit::TableView::FILL)
1563 fillData.PushBack( &dataInstance );
1567 // Second pass: Distribute remaining relative space
1568 const unsigned int fillCount = fillData.Size();
1571 if( relativeTotal > 1.0f )
1573 relativeTotal = 1.0f;
1576 const float evenFillRatio = (1.0f - relativeTotal ) / fillCount;
1578 for( unsigned int i = 0; i < fillCount; ++i )
1580 fillData[ i ]->fillRatio = evenFillRatio;
1585 float TableView::CalculateTotalFixedSize( const RowColumnArray& data )
1587 float totalSize = 0.0f;
1589 const unsigned int dataCount = data.Size();
1591 for( unsigned int i = 0; i < dataCount; ++i )
1593 const RowColumnData& dataInstance = data[ i ];
1595 switch( dataInstance.sizePolicy )
1597 // we have absolute size to FIXED and FIT column/row and relative size for RELATIVE and FILL column/row
1598 case Toolkit::TableView::FIXED:
1599 case Toolkit::TableView::FIT:
1601 totalSize += dataInstance.size;
1615 Vector2 TableView::GetCellPadding( Dimension::Type dimension )
1619 case Dimension::WIDTH:
1621 return Vector2( mPadding.x, mPadding.x );
1623 case Dimension::HEIGHT:
1625 return Vector2( mPadding.y, mPadding.y );
1636 void TableView::CalculateFitSizes( RowColumnArray& data, Dimension::Type dimension )
1638 Vector2 cellPadding = GetCellPadding( dimension );
1640 const unsigned int dataCount = data.Size();
1642 for( unsigned int i = 0; i < dataCount; ++i )
1644 RowColumnData& dataInstance = data[ i ];
1646 if( dataInstance.sizePolicy == Toolkit::TableView::FIT )
1648 // Find the size of the biggest actor in the row or column
1649 float maxActorHeight = 0.0f;
1651 unsigned int fitCount = ( dimension == Dimension::WIDTH ) ? mCellData.GetRows() : mCellData.GetColumns();
1653 for( unsigned int j = 0; j < fitCount; ++j )
1655 unsigned int row = ( dimension == Dimension::WIDTH ) ? j : i;
1656 unsigned int column = ( dimension == Dimension::WIDTH ) ? i : j;
1657 DALI_ASSERT_DEBUG( row < mCellData.GetRows() );
1658 DALI_ASSERT_DEBUG( column < mCellData.GetColumns() );
1660 const CellData& cellData = mCellData[ row ][ column ];
1661 const Actor& actor = cellData.actor;
1664 if( FitToChild( actor, dimension ) && ( dimension == Dimension::WIDTH ) ? ( cellData.position.columnSpan == 1 ) : ( cellData.position.rowSpan == 1 ) )
1666 maxActorHeight = std::max( maxActorHeight, actor.GetRelayoutSize( dimension ) + cellPadding.x + cellPadding.y );
1671 dataInstance.size = maxActorHeight;
1676 bool TableView::FindFit( const RowColumnArray& data )
1678 for( unsigned int i = 0, count = data.Size(); i < count; ++i )
1680 if( data[ i ].sizePolicy == Toolkit::TableView::FIT )
1689 } // namespace Internal
1691 } // namespace Toolkit