/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// currently not called from code so compiler will optimize these away, kept here for future debugging
#define FLEX_CONTAINER_TAG "DALI Toolkit::FlexContainer "
-#define FC_LOG(fmt, args...) Debug::LogMessage(Debug::DebugInfo, FLEX_CONTAINER_TAG fmt, ## args)
-//#define FLEX_CONTAINER_DEBUG 1
+#define FC_LOG(fmt, args,...) Debug::LogMessage(Debug::DebugInfo, FLEX_CONTAINER_TAG fmt, ## args)
+// #define FLEX_CONTAINER_DEBUG 1
#if defined(FLEX_CONTAINER_DEBUG)
-void PrintNode( Toolkit::Internal::FlexContainer::FlexItemNodeContainer itemNodes )
+void PrintNodes( Toolkit::Internal::FlexContainer::FlexItemNodeContainer itemNodes )
{
// Print the style property and layout of all the children
for( unsigned int i = 0; i < itemNodes.size(); ++i )
{
FC_LOG( "Item %d style: \n", i );
- print_css_node( itemNodes[i].node, (css_print_options_t)( CSS_PRINT_STYLE | CSS_PRINT_CHILDREN ) );
+ YGNodePrint( itemNodes[i].node, (YGPrintOptions)( YGPrintOptionsStyle | YGPrintOptionsChildren ) );
+ FC_LOG( "\n" );
FC_LOG( "Item %d layout: \n", i );
- print_css_node( itemNodes[i].node, (css_print_options_t)( CSS_PRINT_LAYOUT | CSS_PRINT_CHILDREN ) );
+ YGNodePrint( itemNodes[i].node, (YGPrintOptions)( YGPrintOptionsLayout | YGPrintOptionsChildren ) );
FC_LOG( "\n" );
}
}
};
const unsigned int ALIGN_CONTENT_STRING_TABLE_COUNT = sizeof( ALIGN_CONTENT_STRING_TABLE ) / sizeof( ALIGN_CONTENT_STRING_TABLE[0] );
-/**
- * The function used by the layout algorithm to be get the style properties
- * and layout information of the child at the given index.
- */
-css_node_t* GetChildNodeAtIndex( void *childrenNodes, int i )
-{
- FlexContainer::FlexItemNodeContainer childrenNodeContainer = *( static_cast<FlexContainer::FlexItemNodeContainer*>( childrenNodes ) );
- return childrenNodeContainer[i].node;
-}
-
-/**
- * The function used by the layout algorithm to check whether the node is dirty
- * for relayout.
- */
-bool IsNodeDirty( void *itemNodes )
-{
- // We only calculate the layout when the child is added or removed, or when
- // style properties are changed. So should always return true here.
- return true;
-}
} // Unnamed namespace
Toolkit::FlexContainer FlexContainer::New()
FlexContainer::~FlexContainer()
{
- free_css_node( mRootNode.node );
+ YGNodeFree( mRootNode.node );
for( unsigned int i = 0; i < mChildrenNodes.size(); i++ )
{
- free_css_node( mChildrenNodes[i].node );
+ YGNodeFree( mChildrenNodes[i].node );
}
mChildrenNodes.clear();
if( mFlexDirection != flexDirection )
{
mFlexDirection = flexDirection;
- mRootNode.node->style.flex_direction = static_cast<css_flex_direction_t>( mFlexDirection );
+ YGNodeStyleSetFlexDirection( mRootNode.node, static_cast<YGFlexDirection>( flexDirection ) );
RelayoutRequest();
}
if( mFlexWrap != flexWrap )
{
mFlexWrap = flexWrap;
- mRootNode.node->style.flex_wrap = static_cast<css_wrap_type_t>( mFlexWrap );
+ YGNodeStyleSetFlexWrap( mRootNode.node, static_cast<YGWrap>( flexWrap ) );
RelayoutRequest();
}
if( mJustifyContent != justifyContent )
{
mJustifyContent = justifyContent;
- mRootNode.node->style.justify_content = static_cast<css_justify_t>( mJustifyContent );
+ YGNodeStyleSetJustifyContent( mRootNode.node, static_cast<YGJustify>( justifyContent ) );
RelayoutRequest();
}
if( mAlignItems != alignItems )
{
mAlignItems = alignItems;
- mRootNode.node->style.align_items = static_cast<css_align_t>( mAlignItems );
+ YGNodeStyleSetAlignItems( mRootNode.node, static_cast<YGAlign>( alignItems ) );
RelayoutRequest();
}
if( mAlignContent != alignContent )
{
mAlignContent = alignContent;
- mRootNode.node->style.align_content = static_cast<css_align_t>( mAlignContent );
+ YGNodeStyleSetAlignContent( mRootNode.node, static_cast<YGAlign>( alignContent ) );
RelayoutRequest();
}
// Create a new node for the child.
FlexItemNode childNode;
childNode.actor = child;
- childNode.node = new_css_node();
- childNode.node->get_child = GetChildNodeAtIndex;
- childNode.node->is_dirty = IsNodeDirty;
- mChildrenNodes.push_back(childNode);
+ childNode.node = YGNodeNew();
+
+ mChildrenNodes.push_back( childNode );
+ YGNodeInsertChild( mRootNode.node, childNode.node, mChildrenNodes.size() - 1 );
Control::OnChildAdd( child );
}
{
if( mChildrenNodes[i].actor.GetHandle() == child )
{
- free_css_node( mChildrenNodes[i].node );
+ YGNodeRemoveChild( mRootNode.node, mChildrenNodes[i].node );
+ YGNodeFree( mChildrenNodes[i].node );
+
mChildrenNodes.erase( mChildrenNodes.begin() + i );
// Relayout the container only if instances were found
if( child )
{
// Anchor actor to top left of the container
- if( child.GetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >() )
+ if( child.GetProperty( Actor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >() )
{
- child.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ child.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
}
- child.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ child.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
float negotiatedWidth = child.GetRelayoutSize(Dimension::WIDTH);
float negotiatedHeight = child.GetRelayoutSize(Dimension::HEIGHT);
if( negotiatedWidth > 0 )
{
- mChildrenNodes[i].node->style.dimensions[CSS_WIDTH] = negotiatedWidth;
+ YGNodeStyleSetWidth( mChildrenNodes[i].node, negotiatedWidth );
}
if( negotiatedHeight > 0 )
{
- mChildrenNodes[i].node->style.dimensions[CSS_HEIGHT] = negotiatedHeight;
+ YGNodeStyleSetHeight( mChildrenNodes[i].node, negotiatedHeight );
}
}
}
// Relayout the container
RelayoutChildren();
+#if defined(FLEX_CONTAINER_DEBUG)
+ PrintNodes( mChildrenNodes );
+#endif
for( unsigned int i = 0; i < mChildrenNodes.size(); i++ )
{
child.SetResizePolicy( ResizePolicy::USE_ASSIGNED_SIZE, Dimension::HEIGHT );
}
}
-
- container.Add( child, Vector2(mChildrenNodes[i].node->layout.dimensions[CSS_WIDTH], mChildrenNodes[i].node->layout.dimensions[CSS_HEIGHT] ) );
+ container.Add( child, Vector2(YGNodeLayoutGetWidth(mChildrenNodes[i].node), YGNodeLayoutGetHeight(mChildrenNodes[i].node) ) );
}
}
}
if( mRootNode.node )
{
Actor self = Self();
-
- mRootNode.node->style.dimensions[CSS_WIDTH] = size.x;
- mRootNode.node->style.dimensions[CSS_HEIGHT] = size.y;
+ YGNodeStyleSetWidth( mRootNode.node, size.x );
+ YGNodeStyleSetHeight( mRootNode.node, size.y );
RelayoutRequest();
}
{
if( mRootNode.node )
{
- mRootNode.node->children_count = mChildrenNodes.size();
-
- // Intialize the layout.
- mRootNode.node->layout.position[CSS_LEFT] = 0;
- mRootNode.node->layout.position[CSS_TOP] = 0;
- mRootNode.node->layout.position[CSS_BOTTOM] = 0;
- mRootNode.node->layout.position[CSS_RIGHT] = 0;
- mRootNode.node->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
- mRootNode.node->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
-
for( unsigned int i = 0; i < mChildrenNodes.size(); i++ )
{
- css_node_t* childNode = mChildrenNodes[i].node;
+ YGNodeRef childNode = mChildrenNodes[i].node;
Actor childActor = mChildrenNodes[i].actor.GetHandle();
- childNode->layout.position[CSS_LEFT] = 0;
- childNode->layout.position[CSS_TOP] = 0;
- childNode->layout.position[CSS_BOTTOM] = 0;
- childNode->layout.position[CSS_RIGHT] = 0;
- childNode->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
- childNode->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
-
// Intialize the style of the child.
- childNode->style.minDimensions[CSS_WIDTH] = childActor.GetMinimumSize().x;
- childNode->style.minDimensions[CSS_HEIGHT] = childActor.GetMinimumSize().y;
- childNode->style.maxDimensions[CSS_WIDTH] = childActor.GetMaximumSize().x;
- childNode->style.maxDimensions[CSS_HEIGHT] = childActor.GetMaximumSize().y;
+ YGNodeStyleSetMinWidth( childNode, childActor.GetProperty< Vector2 >( Actor::Property::MINIMUM_SIZE ).x );
+ YGNodeStyleSetMinHeight( childNode, childActor.GetProperty< Vector2 >( Actor::Property::MINIMUM_SIZE ).y );
+ YGNodeStyleSetMaxWidth( childNode, childActor.GetProperty< Vector2 >( Actor::Property::MAXIMUM_SIZE ).x );
+ YGNodeStyleSetMaxHeight( childNode, childActor.GetProperty< Vector2 >( Actor::Property::MAXIMUM_SIZE ).y );
// Check child properties on the child for how to layout it.
// These properties should be dynamically registered to the child which
if( childActor.GetPropertyType( Toolkit::FlexContainer::ChildProperty::FLEX ) != Property::NONE )
{
- childNode->style.flex = childActor.GetProperty( Toolkit::FlexContainer::ChildProperty::FLEX ).Get<float>();
+ YGNodeStyleSetFlex( childNode, childActor.GetProperty( Toolkit::FlexContainer::ChildProperty::FLEX ).Get<float>() );
}
Toolkit::FlexContainer::Alignment alignSelf( Toolkit::FlexContainer::ALIGN_AUTO );
- if( childActor.GetPropertyType( Toolkit::FlexContainer::FlexContainer::ChildProperty::ALIGN_SELF ) != Property::NONE )
+ if( childActor.GetPropertyType( Toolkit::FlexContainer::ChildProperty::ALIGN_SELF ) != Property::NONE )
{
Property::Value alignSelfPropertyValue = childActor.GetProperty( Toolkit::FlexContainer::ChildProperty::ALIGN_SELF );
if( alignSelfPropertyValue.GetType() == Property::INTEGER )
ALIGN_SELF_STRING_TABLE_COUNT,
alignSelf );
}
+ YGNodeStyleSetAlignSelf( childNode, static_cast<YGAlign>(alignSelf) );
}
- childNode->style.align_self = static_cast<css_align_t>(alignSelf);
if( childActor.GetPropertyType( Toolkit::FlexContainer::ChildProperty::FLEX_MARGIN ) != Property::NONE )
{
Vector4 flexMargin = childActor.GetProperty( Toolkit::FlexContainer::ChildProperty::FLEX_MARGIN ).Get<Vector4>();
- childNode->style.margin[CSS_LEFT] = flexMargin.x;
- childNode->style.margin[CSS_TOP] = flexMargin.y;
- childNode->style.margin[CSS_RIGHT] = flexMargin.z;
- childNode->style.margin[CSS_BOTTOM] = flexMargin.w;
+ YGNodeStyleSetMargin( childNode, YGEdgeLeft, flexMargin.x );
+ YGNodeStyleSetMargin( childNode, YGEdgeTop, flexMargin.y );
+ YGNodeStyleSetMargin( childNode, YGEdgeRight, flexMargin.z );
+ YGNodeStyleSetMargin( childNode, YGEdgeBottom, flexMargin.w );
}
}
// Calculate the layout
- css_direction_t nodeLayoutDirection = CSS_DIRECTION_INHERIT;
+ YGDirection nodeLayoutDirection = YGDirectionInherit;
switch( mContentDirection )
{
case Dali::Toolkit::FlexContainer::LTR:
{
- nodeLayoutDirection = CSS_DIRECTION_LTR;
+ nodeLayoutDirection = YGDirectionLTR;
break;
}
case Dali::Toolkit::FlexContainer::RTL:
{
- nodeLayoutDirection = CSS_DIRECTION_RTL;
+ nodeLayoutDirection = YGDirectionRTL;
break;
}
case Dali::Toolkit::FlexContainer::INHERIT:
{
- nodeLayoutDirection = CSS_DIRECTION_INHERIT;
+ nodeLayoutDirection = YGDirectionInherit;
break;
}
}
- layoutNode( mRootNode.node, Self().GetMaximumSize().x, Self().GetMaximumSize().y, nodeLayoutDirection);
+#if defined(FLEX_CONTAINER_DEBUG)
+ YGNodePrint( mRootNode.node, (YGPrintOptions)( YGPrintOptionsLayout | YGPrintOptionsStyle | YGPrintOptionsChildren ) );
+#endif
+ YGNodeCalculateLayout( mRootNode.node, Self().GetProperty< Vector2 >( Actor::Property::MAXIMUM_SIZE ).x, Self().GetProperty< Vector2 >( Actor::Property::MAXIMUM_SIZE ).y, nodeLayoutDirection );
+#if defined(FLEX_CONTAINER_DEBUG)
+ YGNodePrint( mRootNode.node, (YGPrintOptions)( YGPrintOptionsLayout | YGPrintOptionsStyle | YGPrintOptionsChildren ) );
+#endif
}
}
Dali::Actor child = mChildrenNodes[i].actor.GetHandle();
if( child )
{
- child.SetX( mChildrenNodes[i].node->layout.position[CSS_LEFT] );
- child.SetY( mChildrenNodes[i].node->layout.position[CSS_TOP] );
+ child.SetProperty( Actor::Property::POSITION_X, YGNodeLayoutGetLeft( mChildrenNodes[i].node ) );
+ child.SetProperty( Actor::Property::POSITION_Y, YGNodeLayoutGetTop( mChildrenNodes[i].node ) );
}
}
}
{
break;
}
- } while ( !mChildrenNodes[nextFocusedActorIndex].actor.GetHandle().IsKeyboardFocusable() );
+ } while ( !mChildrenNodes[nextFocusedActorIndex].actor.GetHandle().GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE ) );
break;
}
case Toolkit::Control::KeyboardFocus::RIGHT:
{
break;
}
- } while ( !mChildrenNodes[nextFocusedActorIndex].actor.GetHandle().IsKeyboardFocusable() );
+ } while ( !mChildrenNodes[nextFocusedActorIndex].actor.GetHandle().GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE ) );
break;
}
default:
self.LayoutDirectionChangedSignal().Connect( this, &FlexContainer::OnLayoutDirectionChanged );
mRootNode.actor = self;
- mRootNode.node = new_css_node();
- mRootNode.node->context = &mChildrenNodes;
+ mRootNode.node = YGNodeNew();
+ YGNodeSetContext( mRootNode.node, &mChildrenNodes );
// Set default style
- mRootNode.node->style.direction = static_cast<css_direction_t>( mContentDirection );
- mRootNode.node->style.flex_direction = static_cast<css_flex_direction_t>( mFlexDirection );
- mRootNode.node->style.flex_wrap = static_cast<css_wrap_type_t>( mFlexWrap );
- mRootNode.node->style.justify_content = static_cast<css_justify_t>( mJustifyContent );
- mRootNode.node->style.align_items = static_cast<css_align_t>( mAlignItems );
- mRootNode.node->style.align_content = static_cast<css_align_t>( mAlignContent );
-
- // Set callbacks.
- mRootNode.node->get_child = GetChildNodeAtIndex;
- mRootNode.node->is_dirty = IsNodeDirty;
+ YGNodeStyleSetFlexDirection( mRootNode.node, static_cast<YGFlexDirection>( mFlexDirection ) );
+ YGNodeStyleSetFlexWrap( mRootNode.node, static_cast<YGWrap>( mFlexWrap ) );
+ YGNodeStyleSetJustifyContent( mRootNode.node, static_cast<YGJustify>( mJustifyContent ) );
+ YGNodeStyleSetAlignItems( mRootNode.node, static_cast<YGAlign>( mAlignItems ) );
+ YGNodeStyleSetAlignContent( mRootNode.node, static_cast<YGAlign>( mAlignContent ) );
// Make self as keyboard focusable and focus group
- self.SetKeyboardFocusable( true );
+ self.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE, true );
SetAsKeyboardFocusGroup( true );
}