-//
-// 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) 2014 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/scripting/scripting.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
+ * sets a child property relative to parents size and applies a unit based padding before the relative calculation.
+ * @param[in] scale of parent minus padding between 0 and 1
+ * @param[in] padding in world coordinate units
+ * @param[in] fixed part in world coordinate units
+ * @param[in] size of the parent
+ * @return The relative size with padding.
*/
-struct RelativeToWidthOrHeight
+Vector2 RelativeToSize( const Vector2& scale, const Vector2& padding, const Vector2& fixed, const Vector2& parentSize)
{
- /**
- * 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;
-};
+ return fixed + ( parentSize - padding ) * scale;
+}
#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)
void PrintArray( Array2d<Dali::Toolkit::Internal::TableView::CellData>& array )
{
}
// 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
namespace Toolkit
{
+const Property::Index TableView::PROPERTY_ROWS( Internal::TableView::TABLEVIEW_PROPERTY_START_INDEX );
+const Property::Index TableView::PROPERTY_COLUMNS( Internal::TableView::TABLEVIEW_PROPERTY_START_INDEX + 1 );
+const Property::Index TableView::PROPERTY_CELL_PADDING( Internal::TableView::TABLEVIEW_PROPERTY_START_INDEX + 2 );
+const Property::Index TableView::PROPERTY_LAYOUT_ROWS( Internal::TableView::TABLEVIEW_PROPERTY_START_INDEX + 3 );
+const Property::Index TableView::PROPERTY_LAYOUT_COLUMNS( Internal::TableView::TABLEVIEW_PROPERTY_START_INDEX + 4 );
+
namespace Internal
{
+namespace
+{
+
+const Scripting::StringEnum< Toolkit::TableView::LayoutPolicy > LAYOUT_POLICY_STRING_TABLE[] =
+{
+ { "fixed", Toolkit::TableView::Fixed },
+ { "relative", Toolkit::TableView::Relative },
+ { "fill", Toolkit::TableView::Fill }
+};
+
+const unsigned int LAYOUT_POLICY_STRING_TABLE_COUNT = sizeof(LAYOUT_POLICY_STRING_TABLE) / sizeof( LAYOUT_POLICY_STRING_TABLE[0] );
+
+// Type registration
+BaseHandle Create()
+{
+ return Toolkit::TableView::New(0, 0);
+}
+TypeRegistration mType( typeid(Toolkit::TableView), typeid(Toolkit::Control), Create );
+
+PropertyRegistration property1( mType, "rows", Toolkit::TableView::PROPERTY_ROWS, Property::UNSIGNED_INTEGER, &TableView::SetProperty, &TableView::GetProperty );
+PropertyRegistration property2( mType, "columns", Toolkit::TableView::PROPERTY_COLUMNS, Property::UNSIGNED_INTEGER, &TableView::SetProperty, &TableView::GetProperty );
+PropertyRegistration property3( mType, "cell-padding", Toolkit::TableView::PROPERTY_CELL_PADDING, Property::VECTOR2, &TableView::SetProperty, &TableView::GetProperty );
+PropertyRegistration property4( mType, "layout-rows", Toolkit::TableView::PROPERTY_LAYOUT_ROWS, Property::MAP, &TableView::SetProperty, &TableView::GetProperty );
+PropertyRegistration property5( mType, "layout-columns", Toolkit::TableView::PROPERTY_LAYOUT_COLUMNS, Property::MAP, &TableView::SetProperty, &TableView::GetProperty );
+
+} // namespace
+
Toolkit::TableView TableView::New( unsigned int initialRows, unsigned int initialColumns )
{
// Create the implementation, temporarily owned by this handle on stack
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;
+ std::vector< CellData > lost;
mCellData.DeleteRow( rowIndex, lost );
// need to update the cellinfos for the items that moved
const unsigned int rowCount = mCellData.GetRows();
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;
+ std::vector< CellData > lost;
mCellData.DeleteColumn( columnIndex, lost );
// need to update the cellinfos for the items that moved
const unsigned int rowCount = mCellData.GetRows();
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;
+ std::vector< CellData > lost;
ResizeContainers( rows, columns, lost );
// calculate if we lost rows or columns
unsigned int rowsRemoved = 0;
DALI_ASSERT_ALWAYS( rowIndex < mFixedHeights.size() );
// add the fixed height to the array of fixed heights
mFixedHeights[ rowIndex ] = height;
+ // remove the relative height of the same row
+ mRelativeHeights[ rowIndex ] = 0.f;
// relayout all cells, no lock needed as nothing added or removed
RelayoutRequest();
}
DALI_ASSERT_ALWAYS( rowIndex < mRelativeHeights.size() );
// add the relative height to the array of relative heights
mRelativeHeights[ rowIndex ] = heightPercentage;
+ // remove the fixed height of the same row
+ mFixedHeights[ rowIndex ] = 0.f;
// relayout all cells, no lock needed as nothing added or removed
RelayoutRequest();
}
DALI_ASSERT_ALWAYS( columnIndex < mFixedWidths.size() );
// add the fixed width to the array of fixed column widths
mFixedWidths[ columnIndex ] = width;
+ // remove the relative width of the same column
+ mRelativeWidths[ columnIndex ] = 0.f;
// relayout all cells, no lock needed as nothing added or removed
RelayoutRequest();
}
DALI_ASSERT_ALWAYS( columnIndex < mRelativeWidths.size() );
// add the relative widths to the array of relative widths
mRelativeWidths[ columnIndex ] = widthPercentage;
+ // remove the fixed width of the same column
+ mFixedWidths[ columnIndex ] = 0.f;
// relayout all cells, no lock needed as nothing added or removed
RelayoutRequest();
}
return mRelativeWidths[ columnIndex ];
}
-void TableView::SetLayoutAnimationDuration( float duration )
-{
- mConstraintDuration = duration;
-}
-
-float TableView::GetLayoutAnimationDuration()
-{
- return mConstraintDuration;
-}
-
-void TableView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
+void TableView::OnRelayout( const Vector2& size, ActorSizeContainer& container )
{
float fixedHeightsTotal = 0.0f;
float fixedWidthsTotal = 0.0f;
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 );
+ Vector3 actorPosition( RelativeToSize( relativePosition, positionPadding, fixedPosition, size ) );
+ actor.SetPosition( actorPosition );
// 2. set size
// constrain the actor size to be relative to the size of table
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 );
+ Vector2 actorSize( RelativeToSize( relativeSize, sizePadding, fixedSize, size ) );
+ actor.SetSize(actorSize.x, actorSize.y);
// Relayout Children
- Relayout ( actor, Vector2( relativeWidthFunctor( size.width ), relativeHeightFunctor( size.height ) ), container );
+ Relayout ( actor, actorSize, container );
}
// for position we need to keep track of current fixed width and relative width
// increase for next column
return mCellData.GetColumns();
}
+void TableView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::TableView tableView = Toolkit::TableView::DownCast( Dali::BaseHandle( object ) );
+
+ if( tableView )
+ {
+ TableView& tableViewImpl( GetImpl( tableView ) );
+ switch( index )
+ {
+ case Toolkit::TableView::PROPERTY_ROWS:
+ {
+ if( value.Get<unsigned int>() != tableViewImpl.GetRows() )
+ {
+ tableViewImpl.Resize( value.Get<unsigned int>(), tableViewImpl.GetColumns() );
+ }
+ break;
+ }
+ case Toolkit::TableView::PROPERTY_COLUMNS:
+ {
+ if( value.Get<unsigned int>() != tableViewImpl.GetColumns() )
+ {
+ tableViewImpl.Resize( tableViewImpl.GetRows(), value.Get<unsigned 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, value );
+ break;
+ }
+ case Toolkit::TableView::PROPERTY_LAYOUT_COLUMNS:
+ {
+ SetHeightOrWidthProperty( tableViewImpl, &TableView::SetFixedWidth, &TableView::SetRelativeWidth, value );
+ break;
+ }
+ }
+ }
+}
+
+Property::Value TableView::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::TableView tableView = Toolkit::TableView::DownCast( Dali::BaseHandle( object ) );
+
+ if( tableView )
+ {
+ TableView& tableViewImpl( GetImpl( tableView ) );
+ switch( index )
+ {
+ case Toolkit::TableView::PROPERTY_ROWS:
+ {
+ value = tableViewImpl.GetRows();
+ break;
+ }
+ case Toolkit::TableView::PROPERTY_COLUMNS:
+ {
+ value = 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::OnControlChildAdd( Actor& child )
{
if( mLayoutingChild )
// we're in the middle of laying out children so no point doing anything here
return;
}
+
+ Toolkit::TableView::CellPosition cellPosition;
+ if( child.GetPropertyIndex(Toolkit::TableView::ROW_SPAN_PROPERTY_NAME) != Property::INVALID_INDEX )
+ {
+ cellPosition.rowSpan = static_cast<unsigned int>( child.GetProperty( child.GetPropertyIndex(Toolkit::TableView::ROW_SPAN_PROPERTY_NAME) ).Get<float>() );
+ }
+ if( child.GetPropertyIndex(Toolkit::TableView::COLUMN_SPAN_PROPERTY_NAME) != Property::INVALID_INDEX )
+ {
+ cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( child.GetPropertyIndex(Toolkit::TableView::COLUMN_SPAN_PROPERTY_NAME) ).Get<float>() );
+ }
+ if( child.GetPropertyIndex(Toolkit::TableView::CELL_INDICES_PROPERTY_NAME) != Property::INVALID_INDEX )
+ {
+ Vector2 indices = child.GetProperty( child.GetPropertyIndex(Toolkit::TableView::CELL_INDICES_PROPERTY_NAME) ).Get<Vector2 >();
+ cellPosition.rowIndex = static_cast<unsigned int>( indices.x );
+ cellPosition.columnIndex = static_cast<unsigned int>( indices.y );
+
+ AddChild( child, cellPosition );
+ // donot continue
+ return;
+ }
+
// check if we're already laying out this child somewhere on the table
// walk through the layout data
const unsigned int rowCount = mCellData.GetRows();
}
TableView::TableView( unsigned int initialRows, unsigned int initialColumns )
-: ControlImpl( true ), // requires touch
+: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
mCellData( initialRows, initialColumns ),
- mLayoutingChild( false ),
- mConstraintDuration( DEFAULT_CONSTRAINT_DURATION )
+ mLayoutingChild( false )
{
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 )
{
mCellData.Resize( rows, columns, removed );
// we dont care if these go smaller, data will be regenerated or is not needed anymore
mRelativeWidths.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
}
}
+void TableView::SetHeightOrWidthProperty(TableView& tableViewImpl,
+ void(TableView::*funcFixed)(unsigned int, float),
+ void(TableView::*funcRelative)(unsigned int, float),
+ const Property::Value& value )
+{
+ if( Property::MAP == value.GetType() )
+ {
+ Property::Map map = value.Get<Property::Map>();
+ unsigned int rowIndex(0);
+ for ( unsigned int i = 0, count = map.Count(); i < count; ++i )
+ {
+ Property::Value& item = map.GetValue(i);
+
+ if( std::istringstream(map.GetKey(i)) >> rowIndex // the key is a number
+ && Property::MAP == item.GetType())
+ {
+ if( item.HasKey( "policy" ) && item.HasKey( "value" ) )
+ {
+ Toolkit::TableView::LayoutPolicy policy = Scripting::GetEnumeration< Toolkit::TableView::LayoutPolicy >( item.GetValue("policy").Get<std::string>(), LAYOUT_POLICY_STRING_TABLE, LAYOUT_POLICY_STRING_TABLE_COUNT );
+ if( policy == Toolkit::TableView::Fixed )
+ {
+ (tableViewImpl.*funcFixed)( rowIndex, item.GetValue("value").Get<float>() );
+ }
+ else if( policy == Toolkit::TableView::Relative )
+ {
+ (tableViewImpl.*funcRelative)( rowIndex, item.GetValue("value").Get<float>() );
+ }
+ }
+ }
+ }
+ }
+}
+
+Property::Value TableView::GetRowHeightsPropertyValue()
+{
+ Property::Map map;
+ GetMapPropertyValue( mFixedHeights, mRelativeHeights, map);
+ return Property::Value(map);
+}
+
+Property::Value TableView::GetColumnWidthsPropertyValue()
+{
+ Property::Map map;
+ GetMapPropertyValue( mFixedWidths, mRelativeWidths, map);
+ return Property::Value(map);
+}
+
+void TableView::GetMapPropertyValue( const std::vector<float>& fixedSize, const std::vector<float>& relativeSize, Property::Map& map )
+{
+ std::string fixedPolicy( Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::Fixed, LAYOUT_POLICY_STRING_TABLE, LAYOUT_POLICY_STRING_TABLE_COUNT ) );
+ std::string relativePolicy( Scripting::GetEnumerationName< Toolkit::TableView::LayoutPolicy >( Toolkit::TableView::Relative, LAYOUT_POLICY_STRING_TABLE, LAYOUT_POLICY_STRING_TABLE_COUNT ) );
+
+ size_t count = fixedSize.size();
+ for( size_t index = 0; index < count; index++ )
+ {
+ if( ! EqualsZero( fixedSize[index] ) )
+ {
+ Property::Map item;
+ item[ "policy" ] = fixedPolicy;
+ item[ "value" ] = fixedSize[index];
+
+ map[ static_cast<std::ostringstream*>( &(std::ostringstream() << index ) )->str() ] = item;
+ }
+ else if( ! EqualsZero( relativeSize[index] ) )
+ {
+ Property::Map item;
+ item[ "policy" ] = relativePolicy;
+ item[ "value" ] = relativeSize[index];
+
+ map[ static_cast<std::ostringstream*>( &(std::ostringstream() << index ) )->str() ] = item;
+ }
+ }
+}
+
TableView::~TableView()
{
// nothing to do
}
-Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
{
Actor nextFocusableActor;
switch ( direction )
{
- case Control::Left:
+ case Toolkit::Control::Left:
{
if(--currentColumn < 0)
{
}
break;
}
- case Control::Right:
+ case Toolkit::Control::Right:
{
if(++currentColumn > numberOfColumns - 1)
{
}
break;
}
- case Control::Up:
+ case Toolkit::Control::Up:
{
if(--currentRow < 0)
{
}
break;
}
- case Control::Down:
+ case Toolkit::Control::Down:
{
if(++currentRow > numberOfRows - 1)
{