-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
// CLASS HEADER
-#include "dali-toolkit/internal/controls/table-view/table-view-impl.h"
-#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
+#include <dali-toolkit/internal/controls/table-view/table-view-impl.h>
// EXTERNAL INCLUDES
+#include <sstream>
#include <dali/public-api/object/ref-object.h>
-#include <dlog.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/devel-api/scripting/scripting.h>
+#include <dali/public-api/size-negotiation/relayout-container.h>
+#include <dali/integration-api/debug.h>
using namespace Dali;
-using namespace std;
namespace
{
-// Type registration
-BaseHandle Create()
-{
- return Toolkit::TableView::New(0, 0);
-}
-TypeRegistration mType( typeid(Toolkit::TableView), typeid(Toolkit::Control), Create );
-
-const float DEFAULT_CONSTRAINT_DURATION = 0.0f;
-
/**
- * Constraint that sets a child property relative to parents Width or Height
+ * @brief Should the tableview fit around the given actor
+ *
+ * @param[in] actor The child actor to test against
+ * @param[dimension] The dimension to test against
*/
-struct RelativeToWidthOrHeight
-{
- /**
- * Constraint that is relative (%) to parent width/height and applies a
- * unit based padding before the relative calculation.
- * @param scale of parent minus padding between 0 and 1
- * @param padding in world coordinate units
- * @param fixed part in world coordinate units
- */
- RelativeToWidthOrHeight( float scale, float padding, float fixed )
- : mScaleFactor( scale ),
- mPadding( padding ),
- mFixed( fixed )
- {
- }
-
- inline float operator()( const float& parentWidthOrHeight )
- {
- return mFixed + ( parentWidthOrHeight - mPadding ) * mScaleFactor;
- }
-
- float operator()( const float& current,
- const PropertyInput& parentWidthOrHeight )
- {
- return operator()( parentWidthOrHeight.GetFloat() );
- }
-
- float mScaleFactor;
- float mPadding;
- float mFixed;
-};
+bool FitToChild( Actor actor, Dimension::Type dimension )
+{
+ return actor.GetResizePolicy( dimension ) != ResizePolicy::FILL_TO_PARENT && actor.GetRelayoutSize( dimension ) > 0.0f;
+}
#if defined(DEBUG_ENABLED)
// debugging support, very useful when new features are added or bugs are hunted down
// currently not called from code so compiler will optimize these away, kept here for future debugging
-#define TABLEVIEW_TAG "DALI Toolkit::TableView"
-#define TV_LOG(fmt, args...) LOG(LOG_INFO, TABLEVIEW_TAG, fmt, ## args)
+#define TABLEVIEW_TAG "DALI Toolkit::TableView "
+#define TV_LOG(fmt, args...) Debug::LogMessage(Debug::DebugInfo, TABLEVIEW_TAG fmt, ## args)
+//#define TABLEVIEW_DEBUG 1
+#if defined(TABLEVIEW_DEBUG)
void PrintArray( Array2d<Dali::Toolkit::Internal::TableView::CellData>& array )
{
TV_LOG( "Array2d<CellData> size [%d,%d] \n", array.GetRows(), array.GetColumns() );
{
Dali::Toolkit::Internal::TableView::CellData data = array[i][j];
char actor = ' ';
+ std::string actorName;
if( data.actor )
{
actor = 'A';
+ actorName = data.actor.GetName();
}
- TV_LOG("Array[%d,%d]=%c %d,%d,%d,%d ", i, j, actor,
+ TV_LOG("Array[%d,%d]=%c %s %d,%d,%d,%d ", i, j, actor, actorName.c_str(),
data.position.rowIndex, data.position.columnIndex,
data.position.rowSpan, data.position.columnSpan );
}
}
// debugging support, very useful when new features are added or bugs are hunted down
// currently not called from code so compiler will optimize these away, kept here for future debugging
-void PrintVector( vector<float>& array )
+void PrintVector( std::vector<float>& array )
{
TV_LOG( "vector, size [%d]\n", array.size() );
// print values
}
TV_LOG( "\n" );
}
+#endif // defined(TABLEVIEW_DEBUG)
#endif // defined(DEBUG_ENABLED)
} // namespace
namespace Internal
{
+namespace
+{
+
+// Type registration
+BaseHandle Create()
+{
+ return Toolkit::TableView::New( 0, 0 );
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TableView, Toolkit::Control, Create );
+
+DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "rows", INTEGER, ROWS )
+DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "columns", INTEGER, COLUMNS )
+DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "cellPadding", VECTOR2, CELL_PADDING )
+DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "layoutRows", MAP, LAYOUT_ROWS )
+DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "layoutColumns", MAP, LAYOUT_COLUMNS )
+DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellIndex", VECTOR2, CELL_INDEX )
+DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "rowSpan", FLOAT, ROW_SPAN )
+DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "columnSpan", FLOAT, COLUMN_SPAN )
+DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellHorizontalAlignment", STRING, CELL_HORIZONTAL_ALIGNMENT )
+DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellVerticalAlignment", STRING, CELL_VERTICAL_ALIGNMENT )
+
+DALI_TYPE_REGISTRATION_END()
+
+const Scripting::StringEnum LAYOUT_POLICY_STRING_TABLE[] =
+{
+ { "fixed", Toolkit::TableView::FIXED },
+ { "relative", Toolkit::TableView::RELATIVE },
+ { "fill", Toolkit::TableView::FILL },
+ { "fit", Toolkit::TableView::FIT }
+};
+const unsigned int LAYOUT_POLICY_STRING_TABLE_COUNT = sizeof(LAYOUT_POLICY_STRING_TABLE) / sizeof( LAYOUT_POLICY_STRING_TABLE[0] );
+
+const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+{
+ {"left", HorizontalAlignment::LEFT},
+ {"center", HorizontalAlignment::CENTER},
+ {"right", HorizontalAlignment::RIGHT}
+};
+const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof(HORIZONTAL_ALIGNMENT_STRING_TABLE) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
+
+const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
+{
+ {"top", VerticalAlignment::TOP},
+ {"center", VerticalAlignment::CENTER},
+ {"bottom", VerticalAlignment::BOTTOM}
+};
+const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof(VERTICAL_ALIGNMENT_STRING_TABLE) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
+
+} // Unnamed namespace
+
Toolkit::TableView TableView::New( unsigned int initialRows, unsigned int initialColumns )
{
// Create the implementation, temporarily owned by this handle on stack
return handle;
}
-bool TableView::AddChild( Actor child, Toolkit::TableView::CellPosition position )
+bool TableView::AddChild( Actor& child, const Toolkit::TableView::CellPosition& position )
{
// check that the child is valid
DALI_ASSERT_ALWAYS( child );
// if child is already parented, we adopt it
- if( child.GetParent() )
- {
- child.GetParent().Remove( child );
- }
+ child.Unparent();
+
// check if we need to expand our data array
if( position.rowIndex >= mCellData.GetRows() )
{
// only adding new rows
ResizeContainers( position.rowIndex + 1, mCellData.GetColumns() );
}
+
if( position.columnIndex >= mCellData.GetColumns() )
{
// only adding new columns
ResizeContainers( mCellData.GetRows(), position.columnIndex + 1 );
}
+
// check if there already is something in this cell
if( mCellData[ position.rowIndex ][ position.columnIndex ].actor )
{
return false; // cannot share a cell, it would complicate all logic and not bring much benefit
}
+
RelayoutingLock lock( *this );
// adopt the child
Self().Add( child );
- // put the actor to the main cell
- CellData data;
- data.actor = child;
- data.position = position;
- mCellData[ position.rowIndex ][ position.columnIndex ] = data;
// if child spans multiple rows of columns
- bool spanned = false;
- if( position.rowSpan > 1 )
+ if( ( position.rowSpan > 1 ) && ( position.rowIndex + position.rowSpan > mCellData.GetRows() ) )
{
- // span might go outside table
- if( position.rowIndex + position.rowSpan > mCellData.GetRows() )
- {
- // increase table size for the full span, only increasing rows
- ResizeContainers( position.rowIndex + position.rowSpan, mCellData.GetColumns() );
- }
- spanned = true;
+ // increase table size for the full span, only increasing rows
+ ResizeContainers( position.rowIndex + position.rowSpan, mCellData.GetColumns() );
}
- if( position.columnSpan > 1 )
+
+ if( ( position.columnSpan > 1 ) && ( position.columnIndex + position.columnSpan > mCellData.GetColumns() ) )
{
- // span might go outside table
- if( position.columnIndex + position.columnSpan > mCellData.GetColumns() )
- {
- // increase table size for the full span, only increasing columns
- ResizeContainers( mCellData.GetRows(), position.columnIndex + position.columnSpan );
- }
- spanned = true;
+ // increase table size for the full span, only increasing columns
+ ResizeContainers( mCellData.GetRows(), position.columnIndex + position.columnSpan );
}
- // if it spanned multiple rows, put the cellinfo in all of those
- if( spanned )
+
+ // Fill in all cells that need the data
+ CellData data;
+ data.actor = child;
+ data.position = position;
+
+ for( unsigned int row = position.rowIndex; row < ( position.rowIndex + position.rowSpan ); ++row )
{
- for( unsigned int row = position.rowIndex; row < ( position.rowIndex + position.rowSpan ); ++row )
+ // store same information to all cells, this way we can identify
+ // if a cell is the prime location of an actor or a spanned one
+ for( unsigned int column = position.columnIndex; column < ( position.columnIndex + position.columnSpan ); ++column )
{
// store same information to all cells, this way we can identify
// if a cell is the prime location of an actor or a spanned one
- for( unsigned int column = position.columnIndex; column < ( position.columnIndex + position.columnSpan ); ++column )
- {
- // store same information to all cells, this way we can identify
- // if a cell is the prime location of an actor or a spanned one
- mCellData[ row ][ column ] = data;
- }
+ mCellData[ row ][ column ] = data;
}
}
- // relayout the whole table
+
+ // Relayout the whole table
+ if( mRowData[position.rowIndex].sizePolicy == Toolkit::TableView::FIT && position.rowSpan == 1 )
+ {
+ mRowDirty = true;
+ }
+ if( mColumnData[position.columnIndex].sizePolicy == Toolkit::TableView::FIT && position.columnSpan == 1 )
+ {
+ mColumnDirty = true;
+ }
+
RelayoutRequest();
- return true; // addition successful
+
+ return true; // Addition successful
}
-Actor TableView::GetChildAt( Toolkit::TableView::CellPosition position )
+Actor TableView::GetChildAt( const Toolkit::TableView::CellPosition& position )
{
- // check if we have this row and column in the table
- if( ( position.columnIndex >= mCellData.GetColumns() )||
- ( position.rowIndex >= mCellData.GetRows() ) )
+ if( ( position.rowIndex < mCellData.GetRows() ) && ( position.columnIndex < mCellData.GetColumns() ) )
{
- // return an empty handle
- return Actor();
+ return mCellData[ position.rowIndex ][ position.columnIndex ].actor;
}
- // return the child handle
- return mCellData[ position.rowIndex ][ position.columnIndex ].actor;
+
+ // Return an empty handle
+ return Actor();
}
-Actor TableView::RemoveChildAt( Toolkit::TableView::CellPosition position )
+Actor TableView::RemoveChildAt( const Toolkit::TableView::CellPosition& position )
{
// get the child handle
Actor child = GetChildAt( position );
if( child )
{
RelayoutingLock lock( *this );
- // Remove the child, this will trigger a call to OnControlChildRemove
+ // Remove the child, this will trigger a call to OnChildRemove
Self().Remove( child );
// relayout the table only if instances were found
if( RemoveAllInstances( child ) )
{
+ if( mRowData[position.rowIndex].sizePolicy == Toolkit::TableView::FIT )
+ {
+ mRowDirty = true;
+ }
+ if( mColumnData[position.columnIndex].sizePolicy == Toolkit::TableView::FIT )
+ {
+ mColumnDirty = true;
+ }
RelayoutRequest();
}
}
return child;
}
-bool TableView::FindChildPosition( Actor child, Toolkit::TableView::CellPosition& position )
+bool TableView::FindChildPosition( const Actor& child, Toolkit::TableView::CellPosition& positionOut )
{
- // only find valid child actors
+ // Only find valid child actors
if( child )
{
- // walk through the layout data
+ // Walk through the layout data
const unsigned int rowCount = mCellData.GetRows();
const unsigned int columnCount = mCellData.GetColumns();
+
for( unsigned int row = 0; row < rowCount; ++row )
{
for( unsigned int column = 0; column < columnCount; ++column )
{
if( mCellData[ row ][ column ].actor == child )
{
- position = mCellData[ row ][ column ].position;
+ positionOut = mCellData[ row ][ column ].position;
return true;
}
}
}
}
+
return false;
}
void TableView::InsertRow( unsigned int rowIndex )
{
RelayoutingLock lock( *this );
+
mCellData.InsertRow( rowIndex );
- // need to update the cellinfos for the items that moved
+
+ // Need to update the cell infos for the items that moved
const unsigned int rowCount = mCellData.GetRows();
const unsigned int columnCount = mCellData.GetColumns();
+
for( unsigned int row = 0; row < rowCount; ++row )
{
for( unsigned int column = 0; column < columnCount; ++column )
{
Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
- // if cell is spanning and above and spans to inserted row
- if( ( position.rowSpan > 1 )&&( position.rowIndex <= rowIndex )&&
+
+ // If cell is spanning and above and spans to inserted row
+ if( ( position.rowSpan > 1 ) && ( position.rowIndex <= rowIndex ) &&
( position.rowIndex + position.rowSpan > rowIndex ) )
{
- // increase span by one
+ // Increment span
position.rowSpan++;
- // copy cell to occupy the new column
+
+ // Copy cell to occupy the new column
mCellData[ rowIndex ][ column ] = mCellData[ row ][ column ];
}
- // if below of inserted row, increase row index
- else if( row > rowIndex )
+ else if( row > rowIndex ) // If below of inserted row, increase row index
{
- // increase index by one
+ // Increment index
position.rowIndex++;
}
}
}
- mRelativeSizes.InsertRow( rowIndex );
- // inserting a row requires adjusting the height vectors
- mFixedHeights.insert( mFixedHeights.begin() + rowIndex, 0 );
- mRelativeHeights.insert( mRelativeHeights.begin() + rowIndex, 0 );
+
+ // Expand row data array
+ mRowData.Insert( mRowData.Begin() + rowIndex, RowColumnData() );
+
+ // Sizes may have changed, so relayout
+ mRowDirty = true;
RelayoutRequest();
}
void TableView::DeleteRow( unsigned int rowIndex )
{
- vector< Actor > ignored;
+ std::vector< Actor > ignored;
DeleteRow( rowIndex, ignored );
}
-void TableView::DeleteRow( unsigned int rowIndex, vector<Actor>& removed )
+void TableView::DeleteRow( unsigned int rowIndex, std::vector<Actor>& removed )
{
RelayoutingLock lock( *this );
- vector< CellData > lost;
+
+ // Delete the row
+ std::vector< CellData > lost;
mCellData.DeleteRow( rowIndex, lost );
- // need to update the cellinfos for the items that moved
+
+ // Need to update the cell infos for the items that moved
const unsigned int rowCount = mCellData.GetRows();
const unsigned int columnCount = mCellData.GetColumns();
+
for( unsigned int row = 0; row < rowCount; ++row )
{
for( unsigned int column = 0; column < columnCount; ++column )
{
Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
- // if cell is spanning and above and spans to deleted row
- if( ( position.rowSpan > 1 )&&( position.rowIndex <= rowIndex )&&
+
+ // If cell is spanning and above and spans to deleted row
+ if( ( position.rowSpan > 1 ) && ( position.rowIndex <= rowIndex ) &&
( position.rowIndex + position.rowSpan > rowIndex ) )
{
- // decrease span by one
+ // Decrement span
if( position.rowSpan > 1 )
{
position.rowSpan--;
}
}
- // if below of or at the inserted row, decrease row index
- else if( row >= rowIndex )
+ else if( row >= rowIndex ) // If below of or at the inserted row, decrease row index
{
- // decrease index by one
- if( position.rowIndex > 1 )
+ // Decrement index
+ if( position.rowIndex > 0 )
{
position.rowIndex--;
}
}
}
}
+
// 1 row removed, 0 columns
RemoveAndGetLostActors( lost, removed, 1u, 0u );
- // resize the data structures
- mRelativeSizes.DeleteRow( rowIndex );
- // deleting a row requires adjusting the height vectors
- mFixedHeights.erase( mFixedHeights.begin() + rowIndex );
- mRelativeHeights.erase( mRelativeHeights.begin() + rowIndex );
+
+ // Contract row data array
+ mRowData.Erase( mRowData.Begin() + rowIndex );
+
+ // Sizes may have changed, so relayout
+ mRowDirty = true;
+ // it is possible that the deletion of row leads to remove of child which might further lead to the change of FIT column
+ mColumnDirty = true;
+
RelayoutRequest();
}
void TableView::InsertColumn( unsigned int columnIndex )
{
RelayoutingLock lock( *this );
+
+ // Insert the new column
mCellData.InsertColumn( columnIndex );
- // need to update the cellinfos for the items that moved
+
+ // Need to update the cell infos for the items that moved
const unsigned int rowCount = mCellData.GetRows();
const unsigned int columnCount = mCellData.GetColumns();
+
for( unsigned int row = 0; row < rowCount; ++row )
{
for( unsigned int column = 0; column < columnCount; ++column )
{
Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
- // if cell is spanning and left side and spans to inserted column
- if( ( position.columnSpan > 1 )&&( position.columnIndex <= columnIndex )&&
+
+ // If cell is spanning and left side and spans to inserted column
+ if( ( position.columnSpan > 1 ) && ( position.columnIndex <= columnIndex ) &&
( position.columnIndex + position.columnSpan > columnIndex ) )
{
- // increase span by one
+ // Increment span
position.columnSpan++;
- // copy cell to occupy the new column
+
+ // Copy cell to occupy the new column
mCellData[ row ][ columnIndex ] = mCellData[ row ][ column ];
}
- // if on the right side of inserted column, increase column index
- else if( column > columnIndex )
+ else if( column > columnIndex ) // If on the right side of inserted column, increase column index
{
- // increase index by one
+ // Increment index
position.columnIndex++;
}
}
}
- // relative sizes gets recalculated on Relayout
- mRelativeSizes.InsertColumn( columnIndex );
- // inserting a column requires adjusting the width vectors
- mFixedWidths.insert( mFixedWidths.begin() + columnIndex, 0 );
- mRelativeWidths.insert( mRelativeWidths.begin() + columnIndex, 0 );
+
+ // Expand column data array
+ mColumnData.Insert( mColumnData.Begin() + columnIndex, RowColumnData() );
+
+ // Sizes may have changed so relayout
+ mColumnDirty = true;
RelayoutRequest();
}
void TableView::DeleteColumn( unsigned int columnIndex )
{
- vector< Actor > ignored;
+ std::vector< Actor > ignored;
DeleteColumn( columnIndex, ignored );
}
-void TableView::DeleteColumn( unsigned int columnIndex, vector<Actor>& removed )
+void TableView::DeleteColumn( unsigned int columnIndex, std::vector<Actor>& removed )
{
RelayoutingLock lock( *this );
- vector< CellData > lost;
+
+ // Remove the column
+ std::vector< CellData > lost;
mCellData.DeleteColumn( columnIndex, lost );
- // need to update the cellinfos for the items that moved
+
+ // Need to update the cell infos for the items that moved
const unsigned int rowCount = mCellData.GetRows();
const unsigned int columnCount = mCellData.GetColumns();
+
for( unsigned int row = 0; row < rowCount; ++row )
{
for( unsigned int column = 0; column < columnCount; ++column )
{
Toolkit::TableView::CellPosition& position = mCellData[ row ][ column ].position;
- // if cell is spanning and left side and spans to inserted column
- if( ( position.columnSpan > 1 )&&( position.columnIndex <= columnIndex )&&
+
+ // If cell is spanning and left side and spans to inserted column
+ if( ( position.columnSpan > 1 ) && ( position.columnIndex <= columnIndex ) &&
( position.columnIndex + position.columnSpan > columnIndex ) )
{
- // decrease span by one
+ // Decrement span
if( position.columnSpan > 1 )
{
position.columnSpan--;
}
}
- // if on the right side of or at the inserted column, decrease column index
- else if( column >= columnIndex )
+ else if( column >= columnIndex ) // If on the right side of or at the inserted column, decrease column index
{
- // decrease index by one
+ // Decrement index
if( position.columnIndex > 0 )
{
position.columnIndex--;
}
}
}
+
// 0 rows, 1 column removed
RemoveAndGetLostActors( lost, removed, 0u, 1u );
- // resize the data structures
- mRelativeSizes.DeleteColumn( columnIndex );
- // deleting a column requires adjusting the width vectors
- mFixedWidths.erase( mFixedWidths.begin() + columnIndex );
- mRelativeWidths.erase( mRelativeWidths.begin() + columnIndex );
- // relayout
+
+ // Contract column data array
+ mColumnData.Erase( mColumnData.Begin() + columnIndex );
+
+ // Size may have changed so relayout
+ mColumnDirty = true;
+ // it is possible that the deletion of column leads to remove of child which might further lead to the change of FIT row
+ mRowDirty = true;
+
RelayoutRequest();
}
void TableView::Resize( unsigned int rows, unsigned int columns )
{
- vector< Actor > ignored;
+ std::vector< Actor > ignored;
Resize( rows, columns, ignored );
}
-void TableView::Resize( unsigned int rows, unsigned int columns, vector<Actor>& removed )
+void TableView::Resize( unsigned int rows, unsigned int columns, std::vector<Actor>& removed )
{
RelayoutingLock lock( *this );
+
unsigned int oldRows = GetRows();
unsigned int oldColumns = GetColumns();
- // resize data array
- vector< CellData > lost;
+
+ // Resize data array
+ std::vector< CellData > lost;
ResizeContainers( rows, columns, lost );
- // calculate if we lost rows or columns
+
+ // Calculate if we lost rows
unsigned int rowsRemoved = 0;
unsigned int newRows = GetRows();
+
if( oldRows < newRows )
{
rowsRemoved = newRows - oldRows;
}
+
+ // Calculate if we lost columns
unsigned int columnsRemoved = 0;
unsigned int newColumns = GetColumns();
if( oldColumns < newColumns )
{
rowsRemoved = newColumns - oldColumns;
}
+
RemoveAndGetLostActors( lost, removed, rowsRemoved, columnsRemoved );
- // finally relayout once all actors are removed
+
+ // Sizes may have changed so request a relayout
+ mRowDirty = true;
+ mColumnDirty = true;
RelayoutRequest();
}
void TableView::SetCellPadding( Size padding )
{
- // if padding really changed
+ // If padding really changed
if( padding != mPadding )
{
mPadding = padding;
- // do a relayout
+
RelayoutRequest();
}
}
return mPadding;
}
+void TableView::SetFitHeight( unsigned int rowIndex )
+{
+ DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
+
+ if( mRowData[ rowIndex ].sizePolicy != Toolkit::TableView::FIT )
+ {
+ mRowData[ rowIndex ].sizePolicy = Toolkit::TableView::FIT;
+
+ mRowDirty = true;
+ RelayoutRequest();
+ }
+}
+
+bool TableView::IsFitHeight( unsigned int rowIndex ) const
+{
+ DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
+
+ return mRowData[ rowIndex ].sizePolicy == Toolkit::TableView::FIT;
+}
+
+void TableView::SetFitWidth( unsigned int columnIndex )
+{
+ DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
+
+ if( mColumnData[ columnIndex ].sizePolicy != Toolkit::TableView::FIT )
+ {
+ mColumnData[ columnIndex ].sizePolicy = Toolkit::TableView::FIT;
+
+ mColumnDirty = true;
+ RelayoutRequest();
+ }
+}
+
+bool TableView::IsFitWidth( unsigned int columnIndex ) const
+{
+ DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
+
+ return mColumnData[ columnIndex ].sizePolicy == Toolkit::TableView::FIT;
+}
+
void TableView::SetFixedHeight( unsigned int rowIndex, float height )
{
- DALI_ASSERT_ALWAYS( rowIndex < mFixedHeights.size() );
- // add the fixed height to the array of fixed heights
- mFixedHeights[ rowIndex ] = height;
- // relayout all cells, no lock needed as nothing added or removed
+ DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
+
+ RowColumnData& data = mRowData[ rowIndex ];
+ data.size = height;
+ data.sizePolicy = Toolkit::TableView::FIXED;
+
+ mRowDirty = true;
RelayoutRequest();
}
float TableView::GetFixedHeight( unsigned int rowIndex ) const
{
- DALI_ASSERT_ALWAYS( rowIndex < mFixedHeights.size() );
+ DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
- return mFixedHeights[ rowIndex ];
+ return mRowData[ rowIndex ].size;
}
-void TableView::SetRelativeHeight( unsigned int rowIndex, float heightPercentage )
+void TableView::SetFixedWidth( unsigned int columnIndex, float width )
{
- DALI_ASSERT_ALWAYS( rowIndex < mRelativeHeights.size() );
- // add the relative height to the array of relative heights
- mRelativeHeights[ rowIndex ] = heightPercentage;
- // relayout all cells, no lock needed as nothing added or removed
+ DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
+
+ RowColumnData& data = mColumnData[ columnIndex ];
+ data.size = width;
+ data.sizePolicy = Toolkit::TableView::FIXED;
+
+ mColumnDirty = true;
RelayoutRequest();
}
-float TableView::GetRelativeHeight( unsigned int rowIndex ) const
+float TableView::GetFixedWidth( unsigned int columnIndex ) const
{
- DALI_ASSERT_ALWAYS( rowIndex < mRelativeHeights.size() );
+ DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
- return mRelativeHeights[ rowIndex ];
+ return mColumnData[ columnIndex ].size;
}
-void TableView::SetFixedWidth( unsigned int columnIndex, float width )
+void TableView::SetRelativeHeight( unsigned int rowIndex, float heightPercentage )
{
- DALI_ASSERT_ALWAYS( columnIndex < mFixedWidths.size() );
- // add the fixed width to the array of fixed column widths
- mFixedWidths[ columnIndex ] = width;
- // relayout all cells, no lock needed as nothing added or removed
+ DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
+
+ RowColumnData& data = mRowData[ rowIndex ];
+ data.fillRatio = heightPercentage;
+ data.sizePolicy = Toolkit::TableView::RELATIVE;
+
+ mRowDirty = true;
RelayoutRequest();
}
-float TableView::GetFixedWidth( unsigned int columnIndex ) const
+float TableView::GetRelativeHeight( unsigned int rowIndex ) const
{
- DALI_ASSERT_ALWAYS( columnIndex < mFixedWidths.size() );
+ DALI_ASSERT_ALWAYS( rowIndex < mRowData.Size() );
- return mFixedWidths[ columnIndex ];
+ return mRowData[ rowIndex ].fillRatio;
}
void TableView::SetRelativeWidth( unsigned int columnIndex, float widthPercentage )
{
- DALI_ASSERT_ALWAYS( columnIndex < mRelativeWidths.size() );
- // add the relative widths to the array of relative widths
- mRelativeWidths[ columnIndex ] = widthPercentage;
- // relayout all cells, no lock needed as nothing added or removed
+ DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
+
+ RowColumnData& data = mColumnData[ columnIndex ];
+ data.fillRatio = widthPercentage;
+ data.sizePolicy = Toolkit::TableView::RELATIVE;
+
+ mColumnDirty = true;
RelayoutRequest();
}
float TableView::GetRelativeWidth( unsigned int columnIndex ) const
{
- DALI_ASSERT_ALWAYS( columnIndex < mRelativeWidths.size() );
+ DALI_ASSERT_ALWAYS( columnIndex < mColumnData.Size() );
- return mRelativeWidths[ columnIndex ];
+ return mColumnData[ columnIndex ].fillRatio;
}
-void TableView::SetLayoutAnimationDuration( float duration )
+void TableView::OnCalculateRelayoutSize( Dimension::Type dimension )
{
- mConstraintDuration = duration;
+ if( (dimension & Dimension::WIDTH) && mColumnDirty )
+ {
+ /*
+ * FIXED and FIT have size in pixel
+ * Nothing to do with FIXED, as its value is assigned by user and will not get changed
+ *
+ * Need to update the size for FIT column here
+ */
+ CalculateFitSizes( mColumnData, Dimension::WIDTH );
+
+ /* RELATIVE and FILL have size in ratio
+ * Their size in pixel is not available until we get the negotiated size for the whole table
+ * Nothing to do with RELATIVE, as its ratio is assigned by user and will not get changed
+ *
+ * Need to update the ratio for FILL column here
+ */
+ CalculateFillSizes( mColumnData );
+
+ mFixedTotals.width = CalculateTotalFixedSize( mColumnData );
+ }
+
+ if( (dimension & Dimension::HEIGHT) && mRowDirty )
+ {
+ // refer to the comment above
+ CalculateFitSizes( mRowData, Dimension::HEIGHT );
+
+ // refer to the comment above
+ CalculateFillSizes( mRowData );
+
+ mFixedTotals.height = CalculateTotalFixedSize( mRowData );
+ }
}
-float TableView::GetLayoutAnimationDuration()
+void TableView::OnLayoutNegotiated( float size, Dimension::Type dimension )
{
- return mConstraintDuration;
+ // Update the column sizes
+ if( (dimension & Dimension::WIDTH) && mColumnDirty )
+ {
+ float remainingSize = size - mFixedTotals.width;
+ if( remainingSize < 0.0f )
+ {
+ remainingSize = 0.0f;
+ }
+
+ // update every column position in ColumnData array
+ float cumulatedWidth = 0.0f;
+ for( unsigned int column = 0, columnCount = mCellData.GetColumns(); column < columnCount; ++column )
+ {
+ if( mColumnData[ column ].sizePolicy == Toolkit::TableView::FILL || mColumnData[ column ].sizePolicy == Toolkit::TableView::RELATIVE)
+ {
+ mColumnData[ column ].size = mColumnData[ column ].fillRatio * remainingSize;
+ }
+
+ cumulatedWidth += mColumnData[ column ].size;
+ mColumnData[column].position = cumulatedWidth;
+ }
+
+ mColumnDirty = false;
+ }
+
+ // Update the row sizes
+ if( (dimension & Dimension::HEIGHT) && mRowDirty )
+ {
+ float remainingSize = size - mFixedTotals.height;
+ if( remainingSize < 0.0f )
+ {
+ remainingSize = 0.0f;
+ }
+
+ // update every row position in RowData array
+ float cumulatedHeight = 0.0f;
+ for( unsigned int row = 0, rowCount = mCellData.GetRows(); row < rowCount; ++row )
+ {
+ if( mRowData[ row ].sizePolicy == Toolkit::TableView::FILL || mRowData[ row ].sizePolicy == Toolkit::TableView::RELATIVE)
+ {
+ mRowData[ row ].size = mRowData[ row ].fillRatio * remainingSize;
+ }
+
+ cumulatedHeight += mRowData[ row ].size;
+ mRowData[row].position = cumulatedHeight;
+ }
+
+ mRowDirty = false;
+ }
}
-void TableView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
+void TableView::OnSizeSet( const Vector3& size )
{
- float fixedHeightsTotal = 0.0f;
- float fixedWidthsTotal = 0.0f;
-
- // 1. update the relative sizes and calculate total fixed height and width
- UpdateRelativeSizes( fixedHeightsTotal, fixedWidthsTotal );
+ // If this table view is size negotiated by another actor or control, then the
+ // rows and columns must be recalculated or the new size will not take effect.
+ mRowDirty = mColumnDirty = true;
+ RelayoutRequest();
- // 2. go through the layout data and create constraints
- float cumulatedFixedHeight = 0.0f;
- float cumulatedRelativeHeight = 0.0f;
+ Control::OnSizeSet( size );
+}
- // iterate the table
- const unsigned int rowCount = mCellData.GetRows();
- const unsigned int columnCount = mCellData.GetColumns();
- // float versions of the count + 1 to keep precision
- const float maxRowPlusOne( rowCount + 1 );
- const float maxColumnPlusOne( columnCount + 1 );
- for( unsigned int row = 0; row < rowCount; ++row )
+void TableView::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+ // Go through the layout data
+ for( unsigned int row = 0, rowCount = mCellData.GetRows(); row < rowCount; ++row )
{
- // reset widths at the start of each row
- float cumulatedFixedWidth = 0.0f;
- float cumulatedRelativeWidth = 0.0f;
- for( unsigned int column = 0; column < columnCount; ++column )
+ for( unsigned int column = 0, columnCount = mCellData.GetColumns(); column < columnCount; ++column )
{
- // check if this cell has an actor
- Actor actor = mCellData[ row ][ column ].actor;
- const Toolkit::TableView::CellPosition position = mCellData[ row ][ column ].position;
- // if there is an actor and this is the main cell of the actor
- // an actor can be in multiple cells if its row or columnspan is more than 1
- // we however must only lay out each actor only once
- if( ( actor )&&( position.rowIndex == row )&&( position.columnIndex == column ) )
+ CellData& cellData= mCellData[ row ][ column ];
+ Actor& actor = cellData.actor;
+ const Toolkit::TableView::CellPosition position = cellData.position;
+
+ // If there is an actor and this is the main cell of the actor.
+ // An actor can be in multiple cells if its row or column span is more than 1.
+ // We however must lay out each actor only once.
+ if( actor && position.rowIndex == row && position.columnIndex == column )
{
- // anchor actor correctly
+ // Anchor actor to top left of the cell
actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- // remove old constraints
- actor.RemoveConstraints();
-
- // 1. set position
- // get the row and column indices
- float rowPos( position.rowIndex );
- float colPos( position.columnIndex );
- // constrain the actor position to be relative to the width and height of table
- // minus the padding of course (padding is all around cells)
- Vector2 relativePosition( cumulatedRelativeWidth, cumulatedRelativeHeight );
- // fixed height rows and fixed width cells are considered as padding so
- // they are removed from the total size for relative
- // for position only consider cumulated fixed rows and columns from top and left
- Vector2 positionPadding( maxColumnPlusOne * mPadding.width + fixedWidthsTotal,
- maxRowPlusOne * mPadding.height + fixedHeightsTotal );
- Vector2 fixedPosition( ( colPos + 1.0f ) * mPadding.width + cumulatedFixedWidth,
- ( rowPos + 1.0f ) * mPadding.height + cumulatedFixedHeight );
-
- Constraint widthConstraint = Constraint::New<float>( Actor::POSITION_X,
- ParentSource( Actor::SIZE_WIDTH ),
- RelativeToWidthOrHeight( relativePosition.x, positionPadding.x, fixedPosition.x ) );
-
- Constraint heightConstraint = Constraint::New<float>( Actor::POSITION_Y,
- ParentSource( Actor::SIZE_HEIGHT ),
- RelativeToWidthOrHeight( relativePosition.y, positionPadding.y, fixedPosition.y ) );
-
- widthConstraint.SetApplyTime( mConstraintDuration );
- heightConstraint.SetApplyTime( mConstraintDuration );
-
- // bake constrained position value if constraint is removed
- widthConstraint.SetRemoveAction( Constraint::Bake );
- heightConstraint.SetRemoveAction( Constraint::Bake );
-
- actor.ApplyConstraint( widthConstraint );
- actor.ApplyConstraint( heightConstraint );
-
- // 2. set size
- // constrain the actor size to be relative to the size of table
- // get the relative size for this cell
- Vector2 relativeSize( mRelativeSizes[ row ][ column ] );
- Vector2 fixedSize( mFixedWidths[ column ], mFixedHeights[ row ] );
- // if we span multiple cells, need to sum them all up, both fixed and relative parts
- if( position.rowSpan > 1 )
+
+ Padding padding;
+ actor.GetPadding( padding );
+
+ float left = column > 0 ? mColumnData[column-1].position : 0.f;
+ float right = mColumnData[column+position.columnSpan-1].position;
+ float top = row > 0 ? mRowData[row-1].position : 0.f;
+ float bottom = mRowData[row+position.rowSpan-1].position;
+
+ if( cellData.horizontalAlignment == HorizontalAlignment::LEFT )
{
- for( unsigned int i = 1; i < position.rowSpan; ++i )
- {
- // accumulate the height only
- relativeSize.height += mRelativeSizes[ row + i ][ column ].height;
- fixedSize.height += mFixedHeights[ row + i ];
- }
+ actor.SetX( left + mPadding.width + padding.left );
}
- if( position.columnSpan > 1 )
+ else if( cellData.horizontalAlignment == HorizontalAlignment::RIGHT )
{
- for( unsigned int i = 1; i < position.columnSpan; ++i )
- {
- // accumulate the width only
- relativeSize.width += mRelativeSizes[ row ][ column + i ].width;
- fixedSize.width += mFixedWidths[ column + i ];
- }
+ actor.SetX( right - mPadding.width - padding.right - actor.GetRelayoutSize( Dimension::WIDTH ) );
+ }
+ else //if( cellData.horizontalAlignment == HorizontalAlignment::CENTER )
+ {
+ actor.SetX( (left + right + padding.left - padding.right - actor.GetRelayoutSize( Dimension::WIDTH )) * 0.5f );
+ }
+
+ if( cellData.verticalAlignment == VerticalAlignment::TOP )
+ {
+ actor.SetY( top + mPadding.height + padding.top );
+ }
+ else if( cellData.verticalAlignment == VerticalAlignment::BOTTOM )
+ {
+ actor.SetY( bottom - mPadding.height - padding.bottom - actor.GetRelayoutSize( Dimension::HEIGHT ) );
+ }
+ else //if( cellData.verticalAlignment = VerticalAlignment::CENTER )
+ {
+ actor.SetY( (top + bottom + padding.top - padding.bottom - actor.GetRelayoutSize( Dimension::HEIGHT )) * 0.5f );
}
- // minus the padding from size (padding is all around cells)
- // if item spans multiple columns or rows then less padding is added (default span is 1)
- // fixed height rows and fixed width cells are considered as padding so they are removed
- // from the total available size for relative cells
- Vector2 sizePadding( maxColumnPlusOne * mPadding.width + fixedWidthsTotal,
- maxRowPlusOne * mPadding.height + fixedHeightsTotal );
- // and added to the fixed size multiplied by the span of rows and columns
- fixedSize.width += ( position.columnSpan - 1.0f ) * mPadding.width;
- fixedSize.height += ( position.rowSpan - 1.0f ) * mPadding.height;
-
- RelativeToWidthOrHeight relativeWidthFunctor( relativeSize.x, sizePadding.x, fixedSize.x );
- RelativeToWidthOrHeight relativeHeightFunctor( relativeSize.y, sizePadding.y, fixedSize.y );
-
- widthConstraint = Constraint::New<float>( Actor::SIZE_WIDTH,
- ParentSource( Actor::SIZE_WIDTH ),
- relativeWidthFunctor );
-
- heightConstraint = Constraint::New<float>( Actor::SIZE_HEIGHT,
- ParentSource( Actor::SIZE_HEIGHT ),
- relativeHeightFunctor );
-
- widthConstraint.SetApplyTime( mConstraintDuration );
- heightConstraint.SetApplyTime( mConstraintDuration );
-
- // bake constrained size value if constraint is removed
- widthConstraint.SetRemoveAction( Constraint::Bake );
- heightConstraint.SetRemoveAction( Constraint::Bake );
-
- actor.ApplyConstraint( widthConstraint );
- actor.ApplyConstraint( heightConstraint );
-
- // Relayout Children
- Relayout ( actor, Vector2( relativeWidthFunctor( size.width ), relativeHeightFunctor( size.height ) ), container );
}
- // for position we need to keep track of current fixed width and relative width
- // increase for next column
- cumulatedFixedWidth += mFixedWidths[ column ];
- cumulatedRelativeWidth += mRelativeSizes[ row ][ column ].width;
}
- // for position we need to keep track of current fixed height and relative height
- // increase for next row
- cumulatedFixedHeight += mFixedHeights[ row ];
- cumulatedRelativeHeight += mRelativeSizes[ row ][ 0 ].height; // all columns share same height
}
}
return mCellData.GetColumns();
}
-void TableView::OnControlChildAdd( Actor& child )
+void TableView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
{
- if( mLayoutingChild )
+ Toolkit::TableView tableView = Toolkit::TableView::DownCast( Dali::BaseHandle( object ) );
+
+ if( tableView )
{
- // we're in the middle of laying out children so no point doing anything here
- return;
+ TableView& tableViewImpl( GetImpl( tableView ) );
+ switch( index )
+ {
+ case Toolkit::TableView::Property::ROWS:
+ {
+ int rows = 0;
+ if( value.Get( rows ) && rows >= 0 )
+ {
+ if( static_cast<unsigned int>(rows) != tableViewImpl.GetRows() )
+ {
+ tableViewImpl.Resize( rows, tableViewImpl.GetColumns() );
+ }
+ }
+ break;
+ }
+ case Toolkit::TableView::Property::COLUMNS:
+ {
+ int columns = 0;
+ if( value.Get( columns ) && columns >= 0 )
+ {
+ if( static_cast<unsigned int>( columns ) != tableViewImpl.GetColumns() )
+ {
+ tableViewImpl.Resize( tableViewImpl.GetRows(), value.Get<int>() );
+ }
+ }
+ break;
+ }
+ case Toolkit::TableView::Property::CELL_PADDING:
+ {
+ tableViewImpl.SetCellPadding( value.Get<Vector2>() );
+ break;
+ }
+ case Toolkit::TableView::Property::LAYOUT_ROWS:
+ {
+ SetHeightOrWidthProperty( tableViewImpl, &TableView::SetFixedHeight, &TableView::SetRelativeHeight, &TableView::SetFitHeight, value );
+ break;
+ }
+ case Toolkit::TableView::Property::LAYOUT_COLUMNS:
+ {
+ SetHeightOrWidthProperty( tableViewImpl, &TableView::SetFixedWidth, &TableView::SetRelativeWidth, &TableView::SetFitWidth, value );
+ break;
+ }
+ }
}
- // check if we're already laying out this child somewhere on the table
- // walk through the layout data
- const unsigned int rowCount = mCellData.GetRows();
- const unsigned int columnCount = mCellData.GetColumns();
- // child not yet laid out, find the first free slot
- for( unsigned int row = 0; row < rowCount; ++row )
+}
+
+Property::Value TableView::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::TableView tableView = Toolkit::TableView::DownCast( Dali::BaseHandle( object ) );
+
+ if( tableView )
{
- for( unsigned int column = 0; column < columnCount; ++column )
+ TableView& tableViewImpl( GetImpl( tableView ) );
+ switch( index )
{
- // no actor means free cell
- if( !(mCellData[ row ][ column ].actor) )
+ case Toolkit::TableView::Property::ROWS:
+ {
+ value = static_cast<int>( tableViewImpl.GetRows() );
+ break;
+ }
+ case Toolkit::TableView::Property::COLUMNS:
{
- // put the actor in the cell
+ value = static_cast<int>( tableViewImpl.GetColumns() );
+ break;
+ }
+ case Toolkit::TableView::Property::CELL_PADDING:
+ {
+ value = tableViewImpl.GetCellPadding();
+ break;
+ }
+ case Toolkit::TableView::Property::LAYOUT_ROWS:
+ {
+ value = tableViewImpl.GetRowHeightsPropertyValue();
+ break;
+ }
+ case Toolkit::TableView::Property::LAYOUT_COLUMNS:
+ {
+ value = tableViewImpl.GetColumnWidthsPropertyValue();
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+void TableView::OnChildAdd( Actor& child )
+{
+ if( ! mLayoutingChild )
+ {
+ // Ensure we're not in the middle of laying out children
+
+ // Check child properties on actor to decide its position inside the table
+ HorizontalAlignment::Type horizontalAlignment = HorizontalAlignment::LEFT;
+ VerticalAlignment::Type verticalAlignment = VerticalAlignment::TOP;
+
+ if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ) != Property::NONE )
+ {
+ std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ).Get<std::string >();
+ Scripting::GetEnumeration< HorizontalAlignment::Type >( value.c_str(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+ horizontalAlignment );
+ }
+
+ if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ) != Property::NONE )
+ {
+ std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ).Get<std::string >();
+ Scripting::GetEnumeration< VerticalAlignment::Type >( value.c_str(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+ verticalAlignment );
+ }
+
+ Toolkit::TableView::CellPosition cellPosition;
+ if( child.GetPropertyType( Toolkit::TableView::ChildProperty::ROW_SPAN ) != Property::NONE )
+ {
+ cellPosition.rowSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get<float>() );
+ }
+
+ if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE )
+ {
+ cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get<float>() );
+ }
+
+ if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE )
+ {
+ Vector2 indices = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_INDEX ).Get<Vector2 >();
+ cellPosition.rowIndex = static_cast<unsigned int>( indices.x );
+ cellPosition.columnIndex = static_cast<unsigned int>( indices.y );
+
+ AddChild( child, cellPosition );
+ SetCellAlignment(cellPosition, horizontalAlignment, verticalAlignment);
+ }
+ else
+ {
+ bool availableCellFound = false;
+
+ // Find the first available cell to store the actor in
+ const unsigned int rowCount = mCellData.GetRows();
+ const unsigned int columnCount = mCellData.GetColumns();
+ for( unsigned int row = 0; row < rowCount && !availableCellFound; ++row )
+ {
+ for( unsigned int column = 0; column < columnCount && !availableCellFound; ++column )
+ {
+ if( !(mCellData[ row ][ column ].actor) )
+ {
+ // Put the actor in the cell
+ CellData data;
+ data.actor = child;
+ data.position.columnIndex = column;
+ data.position.rowIndex = row;
+ data.horizontalAlignment = horizontalAlignment;
+ data.verticalAlignment = verticalAlignment;
+ mCellData[ row ][ column ] = data;
+
+ availableCellFound = true;
+ break;
+ }
+ }
+ }
+
+ if( ! availableCellFound )
+ {
+ // No empty cells, so increase size of the table
+ unsigned int newColumnCount = ( columnCount > 0 ) ? columnCount : 1;
+ ResizeContainers( rowCount + 1, newColumnCount );
+
+ // Put the actor in the first cell of the new row
CellData data;
data.actor = child;
- data.position.columnIndex = column;
- data.position.rowIndex = row;
- mCellData[ row ][ column ] = data;
- RelayoutRequest();
- // don' continue
- return;
+ data.position.rowIndex = rowCount;
+ data.position.columnIndex = 0;
+ data.horizontalAlignment = horizontalAlignment;
+ data.verticalAlignment = verticalAlignment;
+ mCellData[ rowCount ][ 0 ] = data;
}
+
+ RelayoutRequest();
}
}
- // still here, no room for the poor child so increase the array. Need a new row
- ResizeContainers( rowCount + 1, columnCount );
- // put the actor to the first cell of the new row
- CellData data;
- data.actor = child;
- data.position.rowIndex = rowCount;
- data.position.columnIndex = 0;
- mCellData[ rowCount ][ 0 ] = data;
- // finally relayout the table
- RelayoutRequest();
+
+ Control::OnChildAdd( child );
}
-void TableView::OnControlChildRemove( Actor& child )
+void TableView::OnChildRemove( Actor& child )
{
// dont process if we're in the middle of bigger operation like delete row, column or resize
if( !mLayoutingChild )
RelayoutRequest();
}
}
+
+ Control::OnChildRemove( child );
}
TableView::TableView( unsigned int initialRows, unsigned int initialColumns )
-: ControlImpl( true ), // requires touch
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
mCellData( initialRows, initialColumns ),
mLayoutingChild( false ),
- mConstraintDuration( DEFAULT_CONSTRAINT_DURATION )
+ mRowDirty( true ), // Force recalculation first time
+ mColumnDirty( true )
{
+ mCurrentColumn = 0;
+ mCurrentRow = 0;
SetKeyboardNavigationSupport( true );
ResizeContainers( initialRows, initialColumns );
}
void TableView::ResizeContainers( unsigned int rows, unsigned int columns )
{
- vector<CellData> ignored;
+ std::vector<CellData> ignored;
ResizeContainers( rows, columns, ignored );
}
-void TableView::ResizeContainers( unsigned int rows, unsigned int columns, vector<CellData>& removed )
+void TableView::ResizeContainers( unsigned int rows, unsigned int columns, std::vector<CellData>& removed )
{
+ // Resize cell data
mCellData.Resize( rows, columns, removed );
- // we dont care if these go smaller, data will be regenerated or is not needed anymore
- mRelativeSizes.Resize( rows, columns );
- mFixedHeights.resize( rows );
- mRelativeHeights.resize( rows );
- mFixedWidths.resize( columns );
- mRelativeWidths.resize( columns );
+
+ // We don't care if these go smaller, data will be regenerated or is not needed anymore
+ mRowData.Resize( rows );
+ mColumnData.Resize( columns );
}
-void TableView::RemoveAndGetLostActors( const vector<CellData>& lost, vector<Actor>& removed,
+void TableView::RemoveAndGetLostActors( const std::vector<CellData>& lost, std::vector<Actor>& removed,
unsigned int rowsRemoved, unsigned int columnsRemoved )
{
// iterate through all lost cells
- vector< CellData >::const_iterator iter = lost.begin();
+ std::vector< CellData >::const_iterator iter = lost.begin();
for( ; iter != lost.end(); ++iter )
{
// if it is a valid actor
}
}
-bool TableView::RemoveAllInstances( Actor child )
+bool TableView::RemoveAllInstances( const Actor& child )
{
bool found = false;
// walk through the layout data
return found;
}
-void TableView::UpdateRelativeSizes( float& fixedHeightsTotal, float& fixedWidthsTotal )
+void TableView::SetHeightOrWidthProperty(TableView& tableViewImpl,
+ void(TableView::*funcFixed)(unsigned int, float),
+ void(TableView::*funcRelative)(unsigned int, float),
+ void(TableView::*funcFit)(unsigned int),
+ const Property::Value& value )
{
- // 1. check all the fixed heights and widths to know how much size they take in total
- // as well as the relative heights and widths to know how much is left for the 'fill' cells
- unsigned int fixedRowCount = 0;
- unsigned int relativeRowCount = 0;
- float relativeHeightsTotal = 0.0f;
- const unsigned int rowCount = mCellData.GetRows();
- for( unsigned int row = 0; row < rowCount; ++row )
+ Property::Map* map = value.GetMap();
+ if( map )
{
- if( mFixedHeights[ row ] > 0.0f )
+ unsigned int index(0);
+ for ( unsigned int i = 0, count = map->Count(); i < count; ++i )
{
- ++fixedRowCount;
- fixedHeightsTotal += mFixedHeights[ row ];
- }
- if( mRelativeHeights[ row ] > 0.0f )
- {
- ++relativeRowCount;
- relativeHeightsTotal += mRelativeHeights[ row ];
- }
- }
- unsigned int fixedColumnCount = 0;
- unsigned int relativeColumnCount = 0;
- const unsigned int columnCount = mCellData.GetColumns();
- float relativeWidthsTotal = 0.0f;
- for( unsigned int column = 0; column < columnCount; ++column )
- {
- if( mFixedWidths[ column ] > 0.0f )
- {
- ++fixedColumnCount;
- fixedWidthsTotal += mFixedWidths[ column ];
- }
- if( mRelativeWidths[ column ] > 0.0f )
- {
- ++relativeColumnCount;
- relativeWidthsTotal += mRelativeWidths[ column ];
+ Property::Value& item = map->GetValue(i);
+ Property::Map* childMap = item.GetMap();
+
+ std::istringstream( map->GetKey(i) ) >> index;
+ if( childMap )
+ {
+ Property::Value* policy = childMap->Find( "policy" );
+ Property::Value* childMapValue = childMap->Find( "value" );
+ if( policy && childMapValue )
+ {
+ std::string policyValue;
+ policy->Get( policyValue );
+ Toolkit::TableView::LayoutPolicy policy;
+ if( Scripting::GetEnumeration< Toolkit::TableView::LayoutPolicy >( policyValue.c_str(),
+ LAYOUT_POLICY_STRING_TABLE,
+ LAYOUT_POLICY_STRING_TABLE_COUNT,
+ policy ) )
+ {
+ if( policy == Toolkit::TableView::FIXED )
+ {
+ (tableViewImpl.*funcFixed)( index, childMapValue->Get<float>() );
+ }
+ else if( policy == Toolkit::TableView::RELATIVE )
+ {
+ (tableViewImpl.*funcRelative)( index, childMapValue->Get<float>() );
+ }
+ else if( policy == Toolkit::TableView::FIT )
+ {
+ (tableViewImpl.*funcFit)( index );
+ }
+ // do nothing for FILL policy
+ }
+ }
+ }
}
}
+}
- // 2. cap the relative width and height totals to 100%
- if( relativeHeightsTotal > 1.0f )
- {
- relativeHeightsTotal = 1.0f;
- }
- if( relativeWidthsTotal > 1.0f )
- {
- relativeWidthsTotal = 1.0f;
- }
+Property::Value TableView::GetRowHeightsPropertyValue()
+{
+ Property::Map map;
+ GetMapPropertyValue( mRowData, map);
+ return Property::Value(map);
+}
- // 3. create a table of relative sizes so we can lookup for cells that span multiple rows & colums
- const float fillRowCount( rowCount - relativeRowCount - fixedRowCount );
- const float fillColumnCount( columnCount - relativeColumnCount - fixedColumnCount );
+Property::Value TableView::GetColumnWidthsPropertyValue()
+{
+ Property::Map map;
+ GetMapPropertyValue( mColumnData, map);
+ return Property::Value(map);
+}
- // walk through the data containers
- for( unsigned int row = 0; row < rowCount; ++row )
+void TableView::GetMapPropertyValue( const RowColumnArray& data, Property::Map& map )
+{
+ const char* fixedPolicy = Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::FIXED,
+ LAYOUT_POLICY_STRING_TABLE,
+ LAYOUT_POLICY_STRING_TABLE_COUNT );
+ const char* relativePolicy = Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::RELATIVE,
+ LAYOUT_POLICY_STRING_TABLE,
+ LAYOUT_POLICY_STRING_TABLE_COUNT );
+ const char* fillPolicy = Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::FILL,
+ LAYOUT_POLICY_STRING_TABLE,
+ LAYOUT_POLICY_STRING_TABLE_COUNT );
+ const char* fitPolicy = Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::FIT,
+ LAYOUT_POLICY_STRING_TABLE,
+ LAYOUT_POLICY_STRING_TABLE_COUNT );
+
+ const RowColumnArray::SizeType count = data.Size();
+ for( RowColumnArray::SizeType i = 0; i < count; i++ )
{
- float relativeHeight = 0.0f;
- // if we have a fixed height, relative height is 0
- if( mFixedHeights[ row ] > 0.0f )
- {
- relativeHeight = 0.0f;
- }
- // else if we're given a specific row height %, use that
- else if( mRelativeHeights[ row ] > 0.0f )
- {
- relativeHeight = mRelativeHeights[ row ];
- }
- // else if there are fill rows
- else if( fillRowCount > 0 )
- {
- // this is a 'fill' row. it gets the remainder of the 100% divided evenly between 'fill' rows
- relativeHeight = (1.0f - relativeHeightsTotal ) / fillRowCount;
- }
- for( unsigned int column = 0; column < columnCount; ++column )
+ const RowColumnData& dataInstance = data[ i ];
+
+ Property::Map item;
+ switch( dataInstance.sizePolicy )
{
- float relativeWidth = 0.0f;
- // if we have a fixed width, relative width is 0
- if( mFixedWidths[ column ] > 0.0f )
+ case Toolkit::TableView::FIXED:
+ {
+ item[ "policy" ] = fixedPolicy;
+ item[ "value" ] = dataInstance.size;
+ break;
+ }
+ case Toolkit::TableView::RELATIVE:
{
- relativeWidth = 0.0f;
+ item[ "policy" ] = relativePolicy;
+ item[ "value" ] = dataInstance.fillRatio;
+ break;
}
- // else if we're given a specific column width %, use that
- else if( mRelativeWidths[ column ] > 0.0f )
+ case Toolkit::TableView::FIT:
{
- relativeWidth = mRelativeWidths[ column ];
+ item[ "policy" ] = fitPolicy;
+ item[ "value" ] = 0.f;
+ break;
}
- // else if there are fill columns
- else if( fillColumnCount > 0 )
+ case Toolkit::TableView::FILL:
+ default:
{
- // this is a 'fill' column. it gets the remainder of the 100% divided evenly between 'fill' columns
- relativeWidth = (1.0f - relativeWidthsTotal ) / fillColumnCount;
+ item[ "policy" ] = fillPolicy;
+ item[ "value" ] = 0.f;
+ break;
}
- // store the value
- mRelativeSizes[ row ][ column ] = Size( relativeWidth, relativeHeight );
}
+ std::ostringstream ss;
+ ss << i;
+ map[ ss.str() ] = item;
}
}
// nothing to do
}
-Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
{
Actor nextFocusableActor;
int numberOfColumns = GetColumns();
int numberOfRows = GetRows();
+ bool lastCell = false;
+ Actor nextValidActor;
+
switch ( direction )
{
- case Control::Left:
+ case Toolkit::Control::KeyboardFocus::LEFT:
+ {
+ do
+ {
+ if(--currentColumn < 0)
+ {
+ currentColumn = numberOfColumns - 1;
+ if(--currentRow < 0)
+ {
+ lastCell = true;
+ currentRow = loopEnabled ? numberOfRows - 1 : 0;
+ focusLost = (currentRow == 0);
+ }
+ }
+ nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+ } while ( !nextValidActor && !lastCell );
+ break;
+ }
+ case Toolkit::Control::KeyboardFocus::RIGHT:
+ {
+ do
+ {
+ if(++currentColumn > numberOfColumns - 1)
+ {
+ currentColumn = 0;
+ if(++currentRow > numberOfRows - 1)
+ {
+ lastCell = true;
+ currentRow = loopEnabled ? 0 : numberOfRows - 1;
+ focusLost = (currentRow == numberOfRows - 1);
+ }
+ }
+ nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+ } while ( !nextValidActor && !lastCell );
+ break;
+ }
+ case Toolkit::Control::KeyboardFocus::UP:
{
- if(--currentColumn < 0)
+ do
{
- currentColumn = numberOfColumns - 1;
if(--currentRow < 0)
{
+ lastCell = true;
currentRow = loopEnabled ? numberOfRows - 1 : 0;
focusLost = (currentRow == 0);
}
- }
+ nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+ } while ( !nextValidActor && !lastCell );
break;
}
- case Control::Right:
+ case Toolkit::Control::KeyboardFocus::DOWN:
+
{
- if(++currentColumn > numberOfColumns - 1)
+ do
{
- currentColumn = 0;
if(++currentRow > numberOfRows - 1)
{
+ lastCell = true;
currentRow = loopEnabled ? 0 : numberOfRows - 1;
focusLost = (currentRow == numberOfRows - 1);
}
- }
+ nextValidActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
+ } while ( !nextValidActor && !lastCell );
break;
}
- case Control::Up:
+ default:
{
- if(--currentRow < 0)
- {
- currentRow = loopEnabled ? numberOfRows - 1 : 0;
- focusLost = (currentRow == 0);
- }
- break;
- }
- case Control::Down:
- {
- if(++currentRow > numberOfRows - 1)
- {
- currentRow = loopEnabled ? 0 : numberOfRows - 1;
- focusLost = (currentRow == numberOfRows - 1);
- }
break;
}
}
// Move the focus if we haven't lost it.
if(!focusLost)
{
+ // Save the new focus cell positions of TableView.
+ mCurrentColumn = currentColumn;
+ mCurrentRow = currentRow;
+
nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn));
}
}
else
{
- // The current focused actor is not within table view, so the child in the first cell should be focused.
- nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
+ // The current focused actor is not within TableView.
+ // This means that the TableView has gained the Focus again.
+
+ unsigned int numberOfColumns = GetColumns();
+ unsigned int numberOfRows = GetRows();
+
+ if( (mCurrentRow != 0 && mCurrentColumn != 0) && // Last saved cell was not the first cell
+ (mCurrentRow != numberOfRows - 1 && mCurrentColumn != numberOfColumns - 1) ) // Last saved cell was not the last cell
+ {
+ // This condition handles the cases when parent TableView gained the focus again after the child layout
+ // container (i.e. TableView) has no more items (i.e. actors) to be focused on in a given direction.
+
+ // Move the focus to next cell towards the given direction in a TableView if the last saved cell was not the first or last cell.
+ nextFocusableActor = GetNextKeyboardFocusableActor(GetChildAt(Toolkit::TableView::CellPosition(mCurrentRow, mCurrentColumn)), direction, loopEnabled);
+ }
+ else
+ {
+ // Otherwise, move the focus to either the first or the last cell according to the given direction.
+ if(direction == Toolkit::Control::KeyboardFocus::LEFT || direction == Toolkit::Control::KeyboardFocus::UP)
+ {
+ nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(numberOfRows - 1, numberOfColumns - 1));
+ }
+ else
+ {
+ nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0));
+ }
+ }
}
}
return nextFocusableActor;
}
+Vector3 TableView::GetNaturalSize()
+{
+ // Natural size is the size of all fixed cell widths or heights. This ignores cells with relative heights.
+ return Vector3( mFixedTotals.width, mFixedTotals.height, 1.0f );
+}
+
+float TableView::CalculateChildSize( const Actor& child, Dimension::Type dimension )
+{
+ Toolkit::TableView::CellPosition position;
+ if( FindChildPosition( child, position) )
+ {
+ switch( dimension )
+ {
+ case Dimension::WIDTH:
+ {
+ float cellSize = 0.0f;
+ cellSize = mColumnData[position.columnIndex+position.columnSpan-1].position
+ - (position.columnIndex > 0 ? mColumnData[position.columnIndex-1].position : 0.f)
+ - mPadding.width * 2.0f;
+
+ if( cellSize < 0.0f )
+ {
+ cellSize = 0.0f;
+ }
+
+ return cellSize;
+ }
+
+ case Dimension::HEIGHT:
+ {
+ float cellSize = 0.0f;
+
+ cellSize = mRowData[position.rowIndex+position.rowSpan-1].position
+ - (position.rowIndex > 0 ? mRowData[position.rowIndex-1].position : 0.f)
+ - mPadding.height * 2.0f;
+
+ if( cellSize < 0.0f )
+ {
+ cellSize = 0.0f;
+ }
+
+ return cellSize;
+ }
+ default:
+ {
+ return 0.0f;
+ }
+ }
+ }
+
+ return 0.0f; // Child not found
+}
+
+bool TableView::RelayoutDependentOnChildren( Dimension::Type dimension )
+{
+ if ( Control::RelayoutDependentOnChildren( dimension ) )
+ {
+ return true;
+ }
+
+ return FindFit( mRowData ) || FindFit( mColumnData );
+}
+
+void TableView::SetCellAlignment( Toolkit::TableView::CellPosition position, HorizontalAlignment::Type horizontal, VerticalAlignment::Type vertical )
+{
+ // Check if we need to expand our data array
+ if( position.rowIndex >= mCellData.GetRows() )
+ {
+ // Only adding new rows
+ ResizeContainers( position.rowIndex + 1, mCellData.GetColumns() );
+ }
+
+ if( position.columnIndex >= mCellData.GetColumns() )
+ {
+ // Only adding new columns
+ ResizeContainers( mCellData.GetRows(), position.columnIndex + 1 );
+ }
+
+ // Set the alignment of the cell
+ CellData& data = mCellData[ position.rowIndex ][ position.columnIndex ];
+ data.horizontalAlignment = horizontal;
+ data.verticalAlignment = vertical;
+}
+
+void TableView::CalculateFillSizes( RowColumnArray& data )
+{
+ // First pass: Count number of fill entries and calculate used relative space
+ Dali::Vector< RowColumnData* > fillData;
+ float relativeTotal = 0.0f;
+
+ const unsigned int dataCount = data.Size();
+
+ for( unsigned int i = 0; i < dataCount; ++i )
+ {
+ RowColumnData& dataInstance = data[ i ];
+
+ if( dataInstance.sizePolicy == Toolkit::TableView::RELATIVE )
+ {
+ relativeTotal += dataInstance.fillRatio;
+ }
+ else if(dataInstance.sizePolicy == Toolkit::TableView::FILL)
+ {
+ fillData.PushBack( &dataInstance );
+ }
+ }
+
+ // Second pass: Distribute remaining relative space
+ const unsigned int fillCount = fillData.Size();
+ if( fillCount > 0 )
+ {
+ if( relativeTotal > 1.0f )
+ {
+ relativeTotal = 1.0f;
+ }
+
+ const float evenFillRatio = (1.0f - relativeTotal ) / fillCount;
+
+ for( unsigned int i = 0; i < fillCount; ++i )
+ {
+ fillData[ i ]->fillRatio = evenFillRatio;
+ }
+ }
+}
+
+float TableView::CalculateTotalFixedSize( const RowColumnArray& data )
+{
+ float totalSize = 0.0f;
+
+ const unsigned int dataCount = data.Size();
+
+ for( unsigned int i = 0; i < dataCount; ++i )
+ {
+ const RowColumnData& dataInstance = data[ i ];
+
+ switch( dataInstance.sizePolicy )
+ {
+ // we have absolute size to FIXED and FIT column/row and relative size for RELATIVE and FILL column/row
+ case Toolkit::TableView::FIXED:
+ case Toolkit::TableView::FIT:
+ {
+ totalSize += dataInstance.size;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ return totalSize;
+}
+
+Vector2 TableView::GetCellPadding( Dimension::Type dimension )
+{
+ switch( dimension )
+ {
+ case Dimension::WIDTH:
+ {
+ return Vector2( mPadding.x, mPadding.x );
+ }
+ case Dimension::HEIGHT:
+ {
+ return Vector2( mPadding.y, mPadding.y );
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return Vector2();
+}
+
+void TableView::CalculateFitSizes( RowColumnArray& data, Dimension::Type dimension )
+{
+ Vector2 cellPadding = GetCellPadding( dimension );
+
+ const unsigned int dataCount = data.Size();
+
+ for( unsigned int i = 0; i < dataCount; ++i )
+ {
+ RowColumnData& dataInstance = data[ i ];
+
+ if( dataInstance.sizePolicy == Toolkit::TableView::FIT )
+ {
+ // Find the size of the biggest actor in the row or column
+ float maxActorHeight = 0.0f;
+
+ unsigned int fitCount = ( dimension == Dimension::WIDTH ) ? mCellData.GetRows() : mCellData.GetColumns();
+
+ for( unsigned int j = 0; j < fitCount; ++j )
+ {
+ unsigned int row = ( dimension == Dimension::WIDTH ) ? j : i;
+ unsigned int column = ( dimension == Dimension::WIDTH ) ? i : j;
+ DALI_ASSERT_DEBUG( row < mCellData.GetRows() );
+ DALI_ASSERT_DEBUG( column < mCellData.GetColumns() );
+
+ const CellData& cellData = mCellData[ row ][ column ];
+ const Actor& actor = cellData.actor;
+ if( actor )
+ {
+ if( FitToChild( actor, dimension ) && ( dimension == Dimension::WIDTH ) ? ( cellData.position.columnSpan == 1 ) : ( cellData.position.rowSpan == 1 ) )
+ {
+ maxActorHeight = std::max( maxActorHeight, actor.GetRelayoutSize( dimension ) + cellPadding.x + cellPadding.y );
+ }
+ }
+ }
+
+ dataInstance.size = maxActorHeight;
+ }
+ }
+}
+
+bool TableView::FindFit( const RowColumnArray& data )
+{
+ for( unsigned int i = 0, count = data.Size(); i < count; ++i )
+ {
+ if( data[ i ].sizePolicy == Toolkit::TableView::FIT )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
} // namespace Internal
} // namespace Toolkit