Merge branch 'tizen' into devel/new_mesh
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / table-view / table-view-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/table-view/table-view-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <sstream>
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/public-api/scripting/scripting.h>
27 #include <dali/public-api/size-negotiation/relayout-container.h>
28 #include <dali/integration-api/debug.h>
29
30 using namespace Dali;
31
32 namespace
33 {
34
35 /**
36  * @brief Should the tableview fit around the given actor
37  *
38  * @param[in] actor The child actor to test against
39  * @param[dimension] The dimnesion to test against
40  */
41 bool FitToChild( Actor actor, Dimension dimension )
42 {
43   return actor.GetResizePolicy( dimension ) != FILL_TO_PARENT && actor.GetRelayoutSize( dimension ) > 0.0f;
44 }
45
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
49
50 #define TABLEVIEW_TAG "DALI Toolkit::TableView "
51 #define TV_LOG(fmt, args...) Debug::LogMessage(Debug::DebugInfo, TABLEVIEW_TAG fmt, ## args)
52
53 void PrintArray( Array2d<Dali::Toolkit::Internal::TableView::CellData>& array )
54 {
55   TV_LOG( "Array2d<CellData> size [%d,%d] \n", array.GetRows(), array.GetColumns() );
56   // print values
57   for( unsigned int i = 0; i < array.GetRows(); ++i )
58   {
59     for( unsigned int j = 0; j < array.GetColumns(); ++j )
60     {
61       Dali::Toolkit::Internal::TableView::CellData data = array[i][j];
62       char actor = ' ';
63       if( data.actor )
64       {
65         actor = 'A';
66       }
67       TV_LOG("Array[%d,%d]=%c %d,%d,%d,%d  ", i, j, actor,
68           data.position.rowIndex, data.position.columnIndex,
69           data.position.rowSpan, data.position.columnSpan );
70     }
71     TV_LOG( "\n" );
72   }
73 }
74
75 // debugging support, very useful when new features are added or bugs are hunted down
76 // currently not called from code so compiler will optimize these away, kept here for future debugging
77 void PrintArray( Array2d<Size>& array )
78 {
79   TV_LOG( "Array2d<Size> size [%d,%d] \n", array.GetRows(), array.GetColumns() );
80   // print values
81   for( unsigned int i = 0; i < array.GetRows(); ++i )
82   {
83     for( unsigned int j = 0; j < array.GetColumns(); ++j )
84     {
85       TV_LOG( "Array[%d,%d]=%.2f,%.2f ", i, j, array[i][j].width, array[i][j].height );
86     }
87     TV_LOG( "\n" );
88   }
89 }
90 // debugging support, very useful when new features are added or bugs are hunted down
91 // currently not called from code so compiler will optimize these away, kept here for future debugging
92 void PrintVector( std::vector<float>& array )
93 {
94   TV_LOG( "vector, size [%d]\n", array.size() );
95   // print values
96   for( unsigned int i = 0; i < array.size(); ++i )
97   {
98     TV_LOG( "vector[%d]=%.2f ", i, array[i] );
99   }
100   TV_LOG( "\n" );
101 }
102 #endif // defined(DEBUG_ENABLED)
103
104 } // namespace
105
106 namespace Dali
107 {
108
109 namespace Toolkit
110 {
111
112 namespace Internal
113 {
114
115 namespace
116 {
117
118 // Type registration
119 BaseHandle Create()
120 {
121   return Toolkit::TableView::New( 0, 0 );
122 }
123
124 // Setup properties, signals and actions using the type-registry.
125 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TableView, Toolkit::Control, Create );
126
127 DALI_PROPERTY_REGISTRATION( TableView, "rows",           UNSIGNED_INTEGER, ROWS           )
128 DALI_PROPERTY_REGISTRATION( TableView, "columns",        UNSIGNED_INTEGER, COLUMNS        )
129 DALI_PROPERTY_REGISTRATION( TableView, "cell-padding",   VECTOR2,          CELL_PADDING   )
130 DALI_PROPERTY_REGISTRATION( TableView, "layout-rows",    MAP,              LAYOUT_ROWS    )
131 DALI_PROPERTY_REGISTRATION( TableView, "layout-columns", MAP,              LAYOUT_COLUMNS )
132
133 DALI_TYPE_REGISTRATION_END()
134
135 const Scripting::StringEnum< Toolkit::TableView::LayoutPolicy > LAYOUT_POLICY_STRING_TABLE[] =
136 {
137  { "fixed",    Toolkit::TableView::FIXED    },
138  { "relative", Toolkit::TableView::RELATIVE },
139  { "fill",     Toolkit::TableView::FILL     }
140 };
141
142 const unsigned int LAYOUT_POLICY_STRING_TABLE_COUNT = sizeof(LAYOUT_POLICY_STRING_TABLE) / sizeof( LAYOUT_POLICY_STRING_TABLE[0] );
143
144 } // Unnamed namespace
145
146 Toolkit::TableView TableView::New( unsigned int initialRows, unsigned int initialColumns )
147 {
148   // Create the implementation, temporarily owned by this handle on stack
149   IntrusivePtr< TableView > impl = new TableView( initialRows, initialColumns );
150
151   // Pass ownership to CustomActor handle
152   Toolkit::TableView handle( *impl );
153
154   // Second-phase init of the implementation
155   // This can only be done after the CustomActor connection has been made...
156   impl->Initialize();
157
158   return handle;
159 }
160
161 bool TableView::AddChild( Actor& child, const Toolkit::TableView::CellPosition& position )
162 {
163   // check that the child is valid
164   DALI_ASSERT_ALWAYS( child );
165
166   // if child is already parented, we adopt it
167   if( child.GetParent() )
168   {
169     child.GetParent().Remove( child );
170   }
171
172   // check if we need to expand our data array
173   if( position.rowIndex >= mCellData.GetRows() )
174   {
175     // only adding new rows
176     ResizeContainers( position.rowIndex + 1, mCellData.GetColumns() );
177   }
178
179   if( position.columnIndex >= mCellData.GetColumns() )
180   {
181     // only adding new columns
182     ResizeContainers( mCellData.GetRows(), position.columnIndex + 1 );
183   }
184
185   // check if there already is something in this cell
186   if( mCellData[ position.rowIndex ][ position.columnIndex ].actor )
187   {
188     return false; // cannot share a cell, it would complicate all logic and not bring much benefit
189   }
190
191   RelayoutingLock lock( *this );
192   // adopt the child
193   Self().Add( child );
194
195   // put the actor to the main cell
196   CellData& data = mCellData[ position.rowIndex ][ position.columnIndex ];
197   data.actor = child;
198   data.position = position;
199
200   // if child spans multiple rows of columns
201   bool spanned = false;
202   if( position.rowSpan > 1 )
203   {
204     // span might go outside table
205     if( position.rowIndex + position.rowSpan > mCellData.GetRows() )
206     {
207       // increase table size for the full span, only increasing rows
208       ResizeContainers( position.rowIndex + position.rowSpan, mCellData.GetColumns() );
209     }
210
211     spanned = true;
212   }
213
214   if( position.columnSpan > 1 )
215   {
216     // span might go outside table
217     if( position.columnIndex + position.columnSpan > mCellData.GetColumns() )
218     {
219       // increase table size for the full span, only increasing columns
220       ResizeContainers( mCellData.GetRows(), position.columnIndex + position.columnSpan );
221     }
222
223     spanned = true;
224   }
225
226   // if it spanned multiple rows, put the cellinfo in all of those
227   if( spanned )
228   {
229     for( unsigned int row = position.rowIndex; row < ( position.rowIndex + position.rowSpan ); ++row )
230     {
231       // store same information to all cells, this way we can identify
232       // if a cell is the prime location of an actor or a spanned one
233       for( unsigned int column = position.columnIndex; column < ( position.columnIndex + position.columnSpan ); ++column )
234       {
235         // store same information to all cells, this way we can identify
236         // if a cell is the prime location of an actor or a spanned one
237         mCellData[ row ][ column ] = data;
238       }
239     }
240   }
241
242   // Relayout the whole table
243   RelayoutRequest();
244
245   return true;    // Addition successful
246 }
247
248 Actor TableView::GetChildAt( const Toolkit::TableView::CellPosition& position )
249 {
250   if( ( position.rowIndex < mCellData.GetRows() ) && ( position.columnIndex < mCellData.GetColumns() ) )
251   {
252     return mCellData[ position.rowIndex ][ position.columnIndex ].actor;
253   }
254
255   // Return an empty handle
256   return Actor();
257 }
258
259 Actor TableView::RemoveChildAt( const Toolkit::TableView::CellPosition& position )
260 {
261   // get the child handle
262   Actor child = GetChildAt( position );
263   // if no real actor there, nothing else to be done
264   if( child )
265   {
266     RelayoutingLock lock( *this );
267     // Remove the child, this will trigger a call to OnControlChildRemove
268     Self().Remove( child );
269
270     // relayout the table only if instances were found
271     if( RemoveAllInstances( child ) )
272     {
273       RelayoutRequest();
274     }
275   }
276   // return the child back to caller
277   return child;
278 }
279
280 bool TableView::FindChildPosition( const Actor& child, Toolkit::TableView::CellPosition& positionOut )
281 {
282   // Only find valid child actors
283   if( child )
284   {
285     // Walk through the layout data
286     const unsigned int rowCount = mCellData.GetRows();
287     const unsigned int columnCount = mCellData.GetColumns();
288
289     for( unsigned int row = 0; row < rowCount; ++row )
290     {
291       for( unsigned int column = 0; column < columnCount; ++column )
292       {
293         if( mCellData[ row ][ column ].actor == child )
294         {
295           positionOut = mCellData[ row ][ column ].position;
296           return true;
297         }
298       }
299     }
300   }
301
302   return false;
303 }
304
305 void TableView::InsertRow( unsigned int rowIndex )
306 {
307   RelayoutingLock lock( *this );
308
309   mCellData.InsertRow( rowIndex );
310
311   // Need to update the cell infos for the items that moved
312   const unsigned int rowCount = mCellData.GetRows();
313   const unsigned int columnCount = mCellData.GetColumns();
314
315   for( unsigned int row = 0; row < rowCount; ++row )
316   {
317     for( unsigned int column = 0; column < columnCount; ++column )
318     {
319       Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
320
321       // If cell is spanning and above and spans to inserted row
322       if( ( position.rowSpan > 1 ) && ( position.rowIndex <= rowIndex ) &&
323           ( position.rowIndex + position.rowSpan > rowIndex ) )
324       {
325         // Increment span
326         position.rowSpan++;
327
328         // Copy cell to occupy the new column
329         mCellData[ rowIndex ][ column ] = mCellData[ row ][ column ];
330       }
331       else if( row > rowIndex )   // If below of inserted row, increase row index
332       {
333         // Increment index
334         position.rowIndex++;
335       }
336     }
337   }
338
339   // Expand row data array
340   mRowData.Insert( mRowData.Begin() + rowIndex, RowColumnData() );
341
342   // Sizes may have changed, so relayout
343   mRowColumnDirty = true;
344   RelayoutRequest();
345 }
346
347 void TableView::DeleteRow( unsigned int rowIndex )
348 {
349   std::vector< Actor > ignored;
350   DeleteRow( rowIndex, ignored );
351 }
352
353 void TableView::DeleteRow( unsigned int rowIndex, std::vector<Actor>& removed )
354 {
355   RelayoutingLock lock( *this );
356
357   // Delete the row
358   std::vector< CellData > lost;
359   mCellData.DeleteRow( rowIndex, lost );
360
361   // Need to update the cell infos for the items that moved
362   const unsigned int rowCount = mCellData.GetRows();
363   const unsigned int columnCount = mCellData.GetColumns();
364
365   for( unsigned int row = 0; row < rowCount; ++row )
366   {
367     for( unsigned int column = 0; column < columnCount; ++column )
368     {
369       Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
370
371       // If cell is spanning and above and spans to deleted row
372       if( ( position.rowSpan > 1 ) && ( position.rowIndex <= rowIndex ) &&
373           ( position.rowIndex + position.rowSpan > rowIndex ) )
374       {
375         // Decrement span
376         if( position.rowSpan > 1 )
377         {
378           position.rowSpan--;
379         }
380       }
381       else if( row >= rowIndex )    // If below of or at the inserted row, decrease row index
382       {
383         // Decrement index
384         if( position.rowIndex > 1 )
385         {
386           position.rowIndex--;
387         }
388       }
389     }
390   }
391
392   // 1 row removed, 0 columns
393   RemoveAndGetLostActors( lost, removed, 1u, 0u );
394
395   // Contract row data array
396   mRowData.Erase( mRowData.Begin() + rowIndex );
397
398   // Sizes may have changed, so relayout
399   mRowColumnDirty = true;
400   RelayoutRequest();
401 }
402
403 void TableView::InsertColumn( unsigned int columnIndex )
404 {
405   RelayoutingLock lock( *this );
406
407   // Insert the new column
408   mCellData.InsertColumn( columnIndex );
409
410   // Need to update the cell infos for the items that moved
411   const unsigned int rowCount = mCellData.GetRows();
412   const unsigned int columnCount = mCellData.GetColumns();
413
414   for( unsigned int row = 0; row < rowCount; ++row )
415   {
416     for( unsigned int column = 0; column < columnCount; ++column )
417     {
418       Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
419
420       // If cell is spanning and left side and spans to inserted column
421       if( ( position.columnSpan > 1 ) && ( position.columnIndex <= columnIndex ) &&
422           ( position.columnIndex + position.columnSpan > columnIndex ) )
423       {
424         // Increment span
425         position.columnSpan++;
426
427         // Copy cell to occupy the new column
428         mCellData[ row ][ columnIndex ] = mCellData[ row ][ column ];
429       }
430       else if( column > columnIndex )   // If on the right side of inserted column, increase column index
431       {
432         // Increment index
433         position.columnIndex++;
434       }
435     }
436   }
437
438   // Expand column data array
439   mColumnData.Insert( mColumnData.Begin() + columnIndex, RowColumnData() );
440
441   // Sizes may have changed so relayout
442   mRowColumnDirty = true;
443   RelayoutRequest();
444 }
445
446 void TableView::DeleteColumn( unsigned int columnIndex )
447 {
448   std::vector< Actor > ignored;
449   DeleteColumn( columnIndex, ignored );
450 }
451
452 void TableView::DeleteColumn( unsigned int columnIndex, std::vector<Actor>& removed )
453 {
454   RelayoutingLock lock( *this );
455
456   // Remove the column
457   std::vector< CellData > lost;
458   mCellData.DeleteColumn( columnIndex, lost );
459
460   // Need to update the cell infos for the items that moved
461   const unsigned int rowCount = mCellData.GetRows();
462   const unsigned int columnCount = mCellData.GetColumns();
463
464   for( unsigned int row = 0; row < rowCount; ++row )
465   {
466     for( unsigned int column = 0; column < columnCount; ++column )
467     {
468       Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
469
470       // If cell is spanning and left side and spans to inserted column
471       if( ( position.columnSpan > 1 ) && ( position.columnIndex <= columnIndex ) &&
472           ( position.columnIndex + position.columnSpan > columnIndex ) )
473       {
474         // Decrement span
475         if( position.columnSpan > 1 )
476         {
477           position.columnSpan--;
478         }
479       }
480       else if( column >= columnIndex )    // If on the right side of or at the inserted column, decrease column index
481       {
482         // Decrement index
483         if( position.columnIndex > 0 )
484         {
485           position.columnIndex--;
486         }
487       }
488     }
489   }
490
491   // 0 rows, 1 column removed
492   RemoveAndGetLostActors( lost, removed, 0u, 1u );
493
494   // Contract column data array
495   mColumnData.Erase( mColumnData.Begin() + columnIndex );
496
497   // Size may have changed so relayout
498   mRowColumnDirty = true;
499   RelayoutRequest();
500 }
501
502 void TableView::Resize( unsigned int rows, unsigned int columns )
503 {
504   std::vector< Actor > ignored;
505   Resize( rows, columns, ignored );
506 }
507
508 void TableView::Resize( unsigned int rows, unsigned int columns, std::vector<Actor>& removed )
509 {
510   RelayoutingLock lock( *this );
511
512   unsigned int oldRows = GetRows();
513   unsigned int oldColumns = GetColumns();
514
515   // Resize data array
516   std::vector< CellData > lost;
517   ResizeContainers( rows, columns, lost );
518
519   // Calculate if we lost rows
520   unsigned int rowsRemoved = 0;
521   unsigned int newRows = GetRows();
522
523   if( oldRows < newRows )
524   {
525     rowsRemoved = newRows - oldRows;
526   }
527
528   // Calculate if we lost columns
529   unsigned int columnsRemoved = 0;
530   unsigned int newColumns = GetColumns();
531   if( oldColumns < newColumns )
532   {
533     rowsRemoved = newColumns - oldColumns;
534   }
535
536   RemoveAndGetLostActors( lost, removed, rowsRemoved, columnsRemoved );
537
538   // Sizes may have changed so request a relayout
539   mRowColumnDirty = true;
540   RelayoutRequest();
541 }
542
543 void TableView::SetCellPadding( Size padding )
544 {
545   // If padding really changed
546   if( padding != mPadding )
547   {
548     mPadding = padding;
549
550     RelayoutRequest();
551   }
552 }
553
554 Size TableView::GetCellPadding()
555 {
556   return mPadding;
557 }
558
559 void TableView::SetRowPolicy( unsigned int rowIndex, CellSizePolicy policy )
560 {
561   DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
562
563   if( mRowData[ rowIndex ].sizePolicy != policy )
564   {
565     mRowData[ rowIndex ].sizePolicy = policy;
566
567     mRowColumnDirty = true;
568     RelayoutRequest();
569   }
570 }
571
572 TableView::CellSizePolicy TableView::GetRowPolicy( unsigned int rowIndex ) const
573 {
574   DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
575
576   return mRowData[ rowIndex ].sizePolicy;
577 }
578
579 void TableView::SetColumnPolicy( unsigned int columnIndex, CellSizePolicy policy )
580 {
581   DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
582
583   if( mColumnData[ columnIndex ].sizePolicy != policy )
584   {
585     mColumnData[ columnIndex ].sizePolicy = policy;
586
587     mRowColumnDirty = true;
588     RelayoutRequest();
589   }
590 }
591
592 TableView::CellSizePolicy TableView::GetColumnPolicy( unsigned int columnIndex ) const
593 {
594   DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
595
596   return mColumnData[ columnIndex ].sizePolicy;
597 }
598
599 void TableView::SetFixedHeight( unsigned int rowIndex, float height )
600 {
601   DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
602
603   RowColumnData& data = mRowData[ rowIndex ];
604   data.size = height;
605   data.sizePolicy = FIXED;
606
607   mRowColumnDirty = true;
608   RelayoutRequest();
609 }
610
611 float TableView::GetFixedHeight( unsigned int rowIndex ) const
612 {
613   DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
614
615   return mRowData[ rowIndex ].size;
616 }
617
618 void TableView::SetFixedWidth( unsigned int columnIndex, float width )
619 {
620   DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
621
622   RowColumnData& data = mColumnData[ columnIndex ];
623   data.size = width;
624   data.sizePolicy = FIXED;
625
626   mRowColumnDirty = true;
627   RelayoutRequest();
628 }
629
630 float TableView::GetFixedWidth( unsigned int columnIndex ) const
631 {
632   DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
633
634   return mColumnData[ columnIndex ].size;
635 }
636
637 void TableView::SetRelativeHeight( unsigned int rowIndex, float heightPercentage )
638 {
639   DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
640
641   RowColumnData& data = mRowData[ rowIndex ];
642   data.fillRatio = heightPercentage;
643   data.userFillRatio = true;
644   data.sizePolicy = FILL;
645
646   mRowColumnDirty = true;
647   RelayoutRequest();
648 }
649
650 float TableView::GetRelativeHeight( unsigned int rowIndex ) const
651 {
652   DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
653
654   return mRowData[ rowIndex ].fillRatio;
655 }
656
657 void TableView::SetRelativeWidth( unsigned int columnIndex, float widthPercentage )
658 {
659   DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
660
661   RowColumnData& data = mColumnData[ columnIndex ];
662   data.fillRatio = widthPercentage;
663   data.userFillRatio = true;
664   data.sizePolicy = FILL;
665
666   mRowColumnDirty = true;
667   RelayoutRequest();
668 }
669
670 float TableView::GetRelativeWidth( unsigned int columnIndex ) const
671 {
672   DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
673
674   return mColumnData[ columnIndex ].fillRatio;
675 }
676
677 void TableView::CalculateRowColumnData()
678 {
679   // Calculate the relative sizes
680   if( mRowColumnDirty )
681   {
682     ComputeRelativeSizes( mRowData );
683     ComputeRelativeSizes( mColumnData );
684
685     mRowColumnDirty = false;
686   }
687 }
688
689 void TableView::OnCalculateRelayoutSize( Dimension dimension )
690 {
691   CalculateRowColumnData();
692
693   if( dimension & WIDTH )
694   {
695     CalculateFixedSizes( mColumnData, WIDTH );
696     mFixedTotals.width = CalculateTotalFixedSize( mColumnData );
697   }
698
699   if( dimension & HEIGHT )
700   {
701     CalculateFixedSizes( mRowData, HEIGHT );
702     mFixedTotals.height = CalculateTotalFixedSize( mRowData );
703   }
704 }
705
706 void TableView::OnLayoutNegotiated( float size, Dimension dimension )
707 {
708   CalculateRowColumnData();
709
710   // Calculate the value of all relative sized rows and columns
711   if( dimension & WIDTH )
712   {
713     float remainingSize = size - mFixedTotals.width;
714     if( remainingSize < 0.0f )
715     {
716       remainingSize = 0.0f;
717     }
718
719     CalculateRelativeSizes( mColumnData, remainingSize );
720   }
721
722   if( dimension & HEIGHT )
723   {
724     float remainingSize = size - mFixedTotals.height;
725     if( remainingSize < 0.0f )
726     {
727       remainingSize = 0.0f;
728     }
729
730     CalculateRelativeSizes( mRowData, remainingSize );
731   }
732 }
733
734 void TableView::OnRelayout( const Vector2& size, RelayoutContainer& container )
735 {
736   CalculateRowColumnData();
737
738   // Go through the layout data
739   float cumulatedHeight = 0.0f;
740
741   const unsigned int rowCount = mCellData.GetRows();
742   const unsigned int columnCount = mCellData.GetColumns();
743
744   for( unsigned int row = 0; row < rowCount; ++row )
745   {
746     float cumulatedWidth = 0.0f;
747
748     for( unsigned int column = 0; column < columnCount; ++column )
749     {
750       Actor& actor = mCellData[ row ][ column ].actor;
751       const Toolkit::TableView::CellPosition position = mCellData[ row ][ column ].position;
752
753       // If there is an actor and this is the main cell of the actor.
754       // An actor can be in multiple cells if its row or columnspan is more than 1.
755       // We however must lay out each actor only once.
756       if( actor && ( position.rowIndex == row ) && ( position.columnIndex == column ) )
757       {
758         // Anchor actor to top left of table view
759         actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
760         actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
761
762         Padding padding;
763         actor.GetPadding( padding );
764
765         Vector3 actorPosition( cumulatedWidth + mPadding.width + padding.left,       // Left padding
766                                cumulatedHeight + mPadding.height + padding.top,      // Top padding
767                                0.0f );
768         actor.SetPosition( actorPosition );
769       }
770
771       DALI_ASSERT_DEBUG( column < mColumnData.Size() );
772       cumulatedWidth += mColumnData[ column ].size;
773     }
774
775     DALI_ASSERT_DEBUG( row < mRowData.Size() );
776     cumulatedHeight += mRowData[ row ].size;
777   }
778 }
779
780 unsigned int TableView::GetRows()
781 {
782   return mCellData.GetRows();
783 }
784
785 unsigned int TableView::GetColumns()
786 {
787   return mCellData.GetColumns();
788 }
789
790 void TableView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
791 {
792   Toolkit::TableView tableView = Toolkit::TableView::DownCast( Dali::BaseHandle( object ) );
793
794   if( tableView )
795   {
796     TableView& tableViewImpl( GetImpl( tableView ) );
797     switch( index )
798     {
799       case Toolkit::TableView::Property::ROWS:
800       {
801         if( value.Get<unsigned int>() != tableViewImpl.GetRows() )
802         {
803           tableViewImpl.Resize( value.Get<unsigned int>(), tableViewImpl.GetColumns() );
804         }
805         break;
806       }
807       case Toolkit::TableView::Property::COLUMNS:
808       {
809         if( value.Get<unsigned int>() != tableViewImpl.GetColumns() )
810         {
811           tableViewImpl.Resize( tableViewImpl.GetRows(), value.Get<unsigned int>() );
812         }
813         break;
814       }
815       case Toolkit::TableView::Property::CELL_PADDING:
816       {
817         tableViewImpl.SetCellPadding( value.Get<Vector2>() );
818         break;
819       }
820       case Toolkit::TableView::Property::LAYOUT_ROWS:
821       {
822         SetHeightOrWidthProperty( tableViewImpl, &TableView::SetFixedHeight, &TableView::SetRelativeHeight, value );
823         break;
824       }
825       case Toolkit::TableView::Property::LAYOUT_COLUMNS:
826       {
827         SetHeightOrWidthProperty( tableViewImpl, &TableView::SetFixedWidth, &TableView::SetRelativeWidth, value );
828         break;
829       }
830     }
831   }
832 }
833
834 Property::Value TableView::GetProperty( BaseObject* object, Property::Index index )
835 {
836   Property::Value value;
837
838   Toolkit::TableView tableView = Toolkit::TableView::DownCast( Dali::BaseHandle( object ) );
839
840   if( tableView )
841   {
842     TableView& tableViewImpl( GetImpl( tableView ) );
843     switch( index )
844     {
845       case Toolkit::TableView::Property::ROWS:
846       {
847         value = tableViewImpl.GetRows();
848         break;
849       }
850       case Toolkit::TableView::Property::COLUMNS:
851       {
852         value = tableViewImpl.GetColumns();
853         break;
854       }
855       case Toolkit::TableView::Property::CELL_PADDING:
856       {
857         value = tableViewImpl.GetCellPadding();
858         break;
859       }
860       case Toolkit::TableView::Property::LAYOUT_ROWS:
861       {
862         value = tableViewImpl.GetRowHeightsPropertyValue();
863         break;
864       }
865       case Toolkit::TableView::Property::LAYOUT_COLUMNS:
866       {
867         value = tableViewImpl.GetColumnWidthsPropertyValue();
868         break;
869       }
870     }
871   }
872
873   return value;
874 }
875
876 void TableView::OnControlChildAdd( Actor& child )
877 {
878   if( mLayoutingChild )
879   {
880     // we're in the middle of laying out children so no point doing anything here
881     return;
882   }
883
884   RelayoutRequest();
885
886   // Test properties on actor
887   Toolkit::TableView::CellPosition cellPosition;
888   if( child.GetPropertyIndex(Toolkit::TableView::ROW_SPAN_PROPERTY_NAME) != Property::INVALID_INDEX )
889   {
890     cellPosition.rowSpan = static_cast<unsigned int>( child.GetProperty( child.GetPropertyIndex(Toolkit::TableView::ROW_SPAN_PROPERTY_NAME) ).Get<float>() );
891   }
892
893   if( child.GetPropertyIndex(Toolkit::TableView::COLUMN_SPAN_PROPERTY_NAME) != Property::INVALID_INDEX )
894   {
895     cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( child.GetPropertyIndex(Toolkit::TableView::COLUMN_SPAN_PROPERTY_NAME) ).Get<float>() );
896   }
897
898   if( child.GetPropertyIndex(Toolkit::TableView::CELL_INDICES_PROPERTY_NAME) != Property::INVALID_INDEX )
899   {
900     Vector2 indices = child.GetProperty( child.GetPropertyIndex(Toolkit::TableView::CELL_INDICES_PROPERTY_NAME) ).Get<Vector2 >();
901     cellPosition.rowIndex = static_cast<unsigned int>( indices.x );
902     cellPosition.columnIndex = static_cast<unsigned int>( indices.y );
903
904     AddChild( child, cellPosition );
905
906     // Do not continue
907     return;
908   }
909
910   // Find the first available cell to store the actor in
911   const unsigned int rowCount = mCellData.GetRows();
912   const unsigned int columnCount = mCellData.GetColumns();
913   for( unsigned int row = 0; row < rowCount; ++row )
914   {
915     for( unsigned int column = 0; column < columnCount; ++column )
916     {
917       if( !(mCellData[ row ][ column ].actor) )
918       {
919         // Put the actor in the cell
920         CellData data;
921         data.actor = child;
922         data.position.columnIndex = column;
923         data.position.rowIndex = row;
924         mCellData[ row ][ column ] = data;
925
926         // Don't continue
927         return;
928       }
929     }
930   }
931
932   // No empty cells, so increase size of the table
933   unsigned int newColumnCount = ( columnCount > 0 ) ? columnCount : 1;
934   ResizeContainers( rowCount + 1, newColumnCount );
935
936   // Put the actor in the first cell of the new row
937   CellData data;
938   data.actor = child;
939   data.position.rowIndex = rowCount;
940   data.position.columnIndex = 0;
941   mCellData[ rowCount ][ 0 ] = data;
942 }
943
944 void TableView::OnControlChildRemove( Actor& child )
945 {
946   // dont process if we're in the middle of bigger operation like delete row, column or resize
947   if( !mLayoutingChild )
948   {
949     // relayout the table only if instances were found
950     if( RemoveAllInstances( child ) )
951     {
952       RelayoutRequest();
953     }
954   }
955 }
956
957 TableView::TableView( unsigned int initialRows, unsigned int initialColumns )
958 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
959   mCellData( initialRows, initialColumns ),
960   mLayoutingChild( false ),
961   mRowColumnDirty( true )     // Force recalculation first time
962 {
963   SetKeyboardNavigationSupport( true );
964   ResizeContainers( initialRows, initialColumns );
965 }
966
967 void TableView::OnInitialize()
968 {
969   // Make self as keyboard focusable and focus group
970   Actor self = Self();
971   self.SetKeyboardFocusable(true);
972   SetAsKeyboardFocusGroup(true);
973 }
974
975 void TableView::ResizeContainers( unsigned int rows, unsigned int columns )
976 {
977   std::vector<CellData> ignored;
978   ResizeContainers( rows, columns, ignored );
979 }
980
981 void TableView::ResizeContainers( unsigned int rows, unsigned int columns, std::vector<CellData>& removed )
982 {
983   // Resize cell data
984   mCellData.Resize( rows, columns, removed );
985
986   // We don't care if these go smaller, data will be regenerated or is not needed anymore
987   mRowData.Resize( rows );
988   mColumnData.Resize( columns );
989 }
990
991 void TableView::RemoveAndGetLostActors( const std::vector<CellData>& lost, std::vector<Actor>& removed,
992                                         unsigned int rowsRemoved, unsigned int columnsRemoved )
993 {
994   // iterate through all lost cells
995   std::vector< CellData >::const_iterator iter = lost.begin();
996   for( ; iter != lost.end(); ++iter )
997   {
998     // if it is a valid actor
999     if( (*iter).actor )
1000     {
1001       // is this actor still somewhere else in the table
1002       Toolkit::TableView::CellPosition position;
1003       if( FindChildPosition( (*iter).actor, position ) )
1004       {
1005         // it must be spanning multiple cells, position contains the top left most one
1006         // check if position is left of the removed location
1007         if( position.columnIndex < (*iter).position.columnIndex )
1008         {
1009           // if column span is greater than 1
1010           if( mCellData[ position.rowIndex ][ position.columnIndex ].position.columnSpan > 1 )
1011           {
1012             // decrease column span
1013             mCellData[ position.rowIndex ][ position.columnIndex ].position.columnSpan -= columnsRemoved;
1014           }
1015         }
1016         // check if position is left of the removed location
1017         if( position.rowIndex < (*iter).position.rowIndex )
1018         {
1019           // if row span is greater than 1
1020           if( mCellData[ position.rowIndex ][ position.columnIndex ].position.rowSpan > 1 )
1021           {
1022             // decrease row span
1023             mCellData[ position.rowIndex ][ position.columnIndex ].position.rowSpan -= rowsRemoved;
1024           }
1025         }
1026       }
1027       else
1028       {
1029         // this actor is gone for good
1030         // add actor to removed container
1031         removed.push_back( (*iter).actor );
1032         // we dont want the child actor anymore
1033         Self().Remove( (*iter).actor );
1034       }
1035     }
1036   }
1037 }
1038
1039 bool TableView::RemoveAllInstances( const Actor& child )
1040 {
1041   bool found = false;
1042   // walk through the layout data
1043   const unsigned int rowCount = mCellData.GetRows();
1044   const unsigned int columnCount = mCellData.GetColumns();
1045   for( unsigned int row = 0; row < rowCount; ++row )
1046   {
1047     for( unsigned int column = 0; column < columnCount; ++column )
1048     {
1049       if( mCellData[ row ][ column ].actor == child )
1050       {
1051         // clear the cell, NOTE that the cell might be spanning multiple cells
1052         mCellData[ row ][ column ] = CellData();
1053         found = true;
1054       }
1055     }
1056   }
1057   return found;
1058 }
1059
1060 void TableView::SetHeightOrWidthProperty(TableView& tableViewImpl,
1061                                          void(TableView::*funcFixed)(unsigned int, float),
1062                                          void(TableView::*funcRelative)(unsigned int, float),
1063                                          const Property::Value& value )
1064 {
1065   if( Property::MAP == value.GetType() )
1066   {
1067     Property::Map map = value.Get<Property::Map>();
1068     unsigned int rowIndex(0);
1069     for ( unsigned int i = 0, count = map.Count(); i < count; ++i )
1070     {
1071       Property::Value& item = map.GetValue(i);
1072
1073       if( std::istringstream(map.GetKey(i)) >> rowIndex  // the key is a number
1074           && Property::MAP == item.GetType())
1075       {
1076         if( item.HasKey( "policy" ) && item.HasKey( "value" ) )
1077         {
1078           Toolkit::TableView::LayoutPolicy policy = Scripting::GetEnumeration< Toolkit::TableView::LayoutPolicy >( item.GetValue("policy").Get<std::string>().c_str(), LAYOUT_POLICY_STRING_TABLE, LAYOUT_POLICY_STRING_TABLE_COUNT );
1079           if( policy == Toolkit::TableView::FIXED )
1080           {
1081             (tableViewImpl.*funcFixed)( rowIndex, item.GetValue("value").Get<float>() );
1082           }
1083           else if( policy == Toolkit::TableView::RELATIVE )
1084           {
1085             (tableViewImpl.*funcRelative)( rowIndex, item.GetValue("value").Get<float>() );
1086           }
1087         }
1088       }
1089     }
1090   }
1091 }
1092
1093 Property::Value TableView::GetRowHeightsPropertyValue()
1094 {
1095   Property::Map map;
1096   GetMapPropertyValue( mRowData, map);
1097   return Property::Value(map);
1098 }
1099
1100 Property::Value TableView::GetColumnWidthsPropertyValue()
1101 {
1102   Property::Map map;
1103   GetMapPropertyValue( mColumnData, map);
1104   return Property::Value(map);
1105 }
1106
1107 void TableView::GetMapPropertyValue( const RowColumnArray& data, Property::Map& map )
1108 {
1109   std::string fixedPolicy( Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::FIXED, LAYOUT_POLICY_STRING_TABLE, LAYOUT_POLICY_STRING_TABLE_COUNT ) );
1110   std::string relativePolicy( Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::RELATIVE, LAYOUT_POLICY_STRING_TABLE, LAYOUT_POLICY_STRING_TABLE_COUNT ) );
1111
1112   const RowColumnArray::SizeType count = data.Size();
1113   for( RowColumnArray::SizeType i = 0; i < count; i++ )
1114   {
1115     const RowColumnData& dataInstance = data[ i ];
1116
1117     switch( dataInstance.sizePolicy )
1118     {
1119       case FIXED:
1120       {
1121         Property::Map item;
1122         item[ "policy" ] = fixedPolicy;
1123         item[ "value" ] = dataInstance.size;
1124
1125         std::ostringstream ss;
1126         ss << i;
1127
1128         map[ ss.str() ] = item;
1129
1130         break;
1131       }
1132
1133       case FILL:
1134       {
1135         Property::Map item;
1136         item[ "policy" ] = relativePolicy;
1137         item[ "value" ] = dataInstance.fillRatio;
1138
1139         std::ostringstream ss;
1140         ss << i;
1141
1142         map[ ss.str() ] = item;
1143
1144         break;
1145       }
1146
1147       default:
1148       {
1149         break;
1150       }
1151     }
1152   }
1153 }
1154
1155 TableView::~TableView()
1156 {
1157   // nothing to do
1158 }
1159
1160 Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
1161 {
1162   Actor nextFocusableActor;
1163
1164   if ( !currentFocusedActor )
1165   {
1166     // Nothing is currently focused, so the child in the first cell should be focused.
1167     nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
1168   }
1169   else
1170   {
1171     Toolkit::TableView::CellPosition position;
1172     if( FindChildPosition( currentFocusedActor, position ) )
1173     {
1174       // The current focused actor is a child of TableView
1175       bool focusLost = false;
1176       int currentRow = position.rowIndex;
1177       int currentColumn = position.columnIndex;
1178       int numberOfColumns = GetColumns();
1179       int numberOfRows = GetRows();
1180
1181       switch ( direction )
1182       {
1183         case Toolkit::Control::Left:
1184         {
1185           if(--currentColumn < 0)
1186           {
1187             currentColumn = numberOfColumns - 1;
1188             if(--currentRow < 0)
1189             {
1190               currentRow = loopEnabled ? numberOfRows - 1 : 0;
1191               focusLost = (currentRow == 0);
1192             }
1193           }
1194           break;
1195         }
1196         case Toolkit::Control::Right:
1197         {
1198           if(++currentColumn > numberOfColumns - 1)
1199           {
1200             currentColumn = 0;
1201             if(++currentRow > numberOfRows - 1)
1202             {
1203               currentRow = loopEnabled ? 0 : numberOfRows - 1;
1204               focusLost = (currentRow == numberOfRows - 1);
1205             }
1206           }
1207           break;
1208         }
1209         case Toolkit::Control::Up:
1210         {
1211           if(--currentRow < 0)
1212           {
1213             currentRow = loopEnabled ? numberOfRows - 1 : 0;
1214             focusLost = (currentRow == 0);
1215           }
1216           break;
1217         }
1218         case Toolkit::Control::Down:
1219
1220         {
1221           if(++currentRow > numberOfRows - 1)
1222           {
1223             currentRow = loopEnabled ? 0 : numberOfRows - 1;
1224             focusLost = (currentRow == numberOfRows - 1);
1225           }
1226           break;
1227         }
1228       }
1229
1230       // Move the focus if we haven't lost it.
1231       if(!focusLost)
1232       {
1233         nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
1234       }
1235     }
1236     else
1237     {
1238       // The current focused actor is not within table view, so the child in the first cell should be focused.
1239       nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
1240     }
1241   }
1242
1243   return nextFocusableActor;
1244 }
1245
1246 Vector3 TableView::GetNaturalSize()
1247 {
1248   // Natural size is the size of all fixed cell widths or heights. This ignores cells with relative heights.
1249   return Vector3( mFixedTotals.width, mFixedTotals.height, 1.0f );
1250 }
1251
1252 float TableView::CalculateChildSize( const Actor& child, Dimension dimension )
1253 {
1254   CalculateRowColumnData();
1255
1256   const unsigned int rowCount = mCellData.GetRows();
1257   const unsigned int columnCount = mCellData.GetColumns();
1258
1259   for( unsigned int row = 0; row < rowCount; ++row )
1260   {
1261     for( unsigned int column = 0; column < columnCount; ++column )
1262     {
1263       // check if this cell has an actor
1264       Actor& actor = mCellData[ row ][ column ].actor;
1265
1266       if( actor && ( actor == child ) )
1267       {
1268         const Toolkit::TableView::CellPosition position = mCellData[ row ][ column ].position;
1269
1270         // If there is an actor and this is the main cell of the actor.
1271         // An actor can be in multiple cells if its row or columnspan is more than 1.
1272         if ( ( position.rowIndex == row ) && ( position.columnIndex == column ) )
1273         {
1274           switch( dimension )
1275           {
1276             case WIDTH:
1277             {
1278               float cellSize = 0.0f;
1279
1280               // Accumulate the width
1281               for( unsigned int i = 0; i < position.columnSpan; ++i )
1282               {
1283                 cellSize += mColumnData[ column + i ].size;
1284               }
1285
1286               // Apply padding
1287               cellSize -= mPadding.width * 2.0f;
1288               if( cellSize < 0.0f )
1289               {
1290                 cellSize = 0.0f;
1291               }
1292
1293               return cellSize;
1294             }
1295
1296             case HEIGHT:
1297             {
1298               float cellSize = 0.0f;
1299
1300               // Accumulate the height
1301               for( unsigned int i = 0; i < position.rowSpan; ++i )
1302               {
1303                 cellSize += mRowData[ row + i ].size;
1304               }
1305
1306               // Apply padding
1307               cellSize -= mPadding.width * 2.0f;
1308               if( cellSize < 0.0f )
1309               {
1310                 cellSize = 0.0f;
1311               }
1312
1313               return cellSize;
1314             }
1315
1316             default:
1317             {
1318               return 0.0f;
1319             }
1320           }
1321         }
1322       }
1323     }
1324   }
1325
1326   return 0.0f;    // Child not found
1327 }
1328
1329 bool TableView::RelayoutDependentOnChildren( Dimension dimension )
1330 {
1331   if ( Control::RelayoutDependentOnChildren( dimension ) )
1332   {
1333     return true;
1334   }
1335
1336   return FindFit( mRowData ) || FindFit( mColumnData );
1337 }
1338
1339 void TableView::SetCellAlignment( Toolkit::TableView::CellPosition position, HorizontalAlignment::Type horizontal, VerticalAlignment::Type vertical )
1340 {
1341   // Check if we need to expand our data array
1342   if( position.rowIndex >= mCellData.GetRows() )
1343   {
1344     // Only adding new rows
1345     ResizeContainers( position.rowIndex + 1, mCellData.GetColumns() );
1346   }
1347
1348   if( position.columnIndex >= mCellData.GetColumns() )
1349   {
1350     // Only adding new columns
1351     ResizeContainers( mCellData.GetRows(), position.columnIndex + 1 );
1352   }
1353
1354   // Set the alignment of the cell
1355   CellData& data = mCellData[ position.rowIndex ][ position.columnIndex ];
1356   data.horizontalAlignment = horizontal;
1357   data.verticalAlignment = vertical;
1358 }
1359
1360 void TableView::ComputeRelativeSizes( RowColumnArray& data )
1361 {
1362   // First pass: Count number of fill entries and calculate used relative space
1363   Dali::Vector< RowColumnData* > fillData;
1364   float relativeTotal = 0.0f;
1365
1366   const unsigned int dataCount = data.Size();
1367
1368   for( unsigned int i = 0; i < dataCount; ++i )
1369   {
1370     RowColumnData& dataInstance = data[ i ];
1371
1372     if( dataInstance.sizePolicy == FILL )
1373     {
1374       if( dataInstance.userFillRatio )
1375       {
1376         relativeTotal += dataInstance.fillRatio;
1377       }
1378       else
1379       {
1380         fillData.PushBack( &dataInstance );
1381       }
1382     }
1383   }
1384
1385   // Second pass: Distribute remaining relative space
1386   const unsigned int fillCount = fillData.Size();
1387   if( fillCount > 0 )
1388   {
1389     if( relativeTotal > 1.0f )
1390     {
1391       relativeTotal = 1.0f;
1392     }
1393
1394     const float evenFillRatio = (1.0f - relativeTotal ) / fillCount;
1395
1396     for( unsigned int i = 0; i < fillCount; ++i )
1397     {
1398       fillData[ i ]->fillRatio = evenFillRatio;
1399     }
1400   }
1401 }
1402
1403 float TableView::CalculateTotalFixedSize( const RowColumnArray& data )
1404 {
1405   float totalSize = 0.0f;
1406
1407   const unsigned int dataCount = data.Size();
1408
1409   for( unsigned int i = 0; i < dataCount; ++i )
1410   {
1411     const RowColumnData& dataInstance = data[ i ];
1412
1413     switch( dataInstance.sizePolicy )
1414     {
1415       case FIXED:
1416       case FIT:
1417       {
1418         totalSize += dataInstance.size;
1419         break;
1420       }
1421
1422       default:
1423       {
1424         break;
1425       }
1426     }
1427   }
1428
1429   return totalSize;
1430 }
1431
1432 void TableView::CalculateFixedSizes( RowColumnArray& data, Dimension dimension )
1433 {
1434   const unsigned int dataCount = data.Size();
1435
1436   for( unsigned int i = 0; i < dataCount; ++i )
1437   {
1438     RowColumnData& dataInstance = data[ i ];
1439
1440     if( dataInstance.sizePolicy == FIT )
1441     {
1442       // Find the size of the biggest actor in the row or column
1443       float maxActorHeight = 0.0f;
1444
1445       unsigned int fitCount = ( dimension == WIDTH ) ? mCellData.GetRows() : mCellData.GetColumns();
1446
1447       for( unsigned int j = 0; j < fitCount; ++j )
1448       {
1449         unsigned int row = ( dimension == WIDTH ) ? j : i;
1450         unsigned int column = ( dimension == WIDTH ) ? i : j;
1451         DALI_ASSERT_DEBUG( row < mCellData.GetRows() );
1452         DALI_ASSERT_DEBUG( column < mCellData.GetColumns() );
1453
1454         Actor& actor = mCellData[ row ][ column ].actor;
1455         if( actor )
1456         {
1457           if( FitToChild( actor, dimension ) )
1458           {
1459             maxActorHeight = std::max( maxActorHeight, actor.GetRelayoutSize( dimension ) );
1460           }
1461         }
1462       }
1463
1464       dataInstance.size = maxActorHeight;
1465     }
1466   }
1467 }
1468
1469 void TableView::CalculateRelativeSizes( RowColumnArray& data, float size )
1470 {
1471   const unsigned int dataCount = data.Size();
1472
1473   for( unsigned int i = 0; i < dataCount; ++i )
1474   {
1475     RowColumnData& dataInstance = data[ i ];
1476
1477     if( dataInstance.sizePolicy == FILL )
1478     {
1479       dataInstance.size = dataInstance.fillRatio * size;
1480     }
1481   }
1482 }
1483
1484 bool TableView::FindFit( const RowColumnArray& data )
1485 {
1486   for( unsigned int i = 0, count = data.Size(); i < count; ++i )
1487   {
1488     if( data[ i ].sizePolicy == FIT )
1489     {
1490       return true;
1491     }
1492   }
1493
1494   return false;
1495 }
1496
1497 } // namespace Internal
1498
1499 } // namespace Toolkit
1500
1501 } // namespace Dali