Fix the build error and runtime coredump in Windows backend
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / layouting / flex-layout-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index ebbf330..0090ec8
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -30,7 +30,7 @@
 #include <dali-toolkit/third-party/yoga/YGNode.h>
 
 #if defined(DEBUG_ENABLED)
-static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_LAYOUT" );
+static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" );
 #endif
 
 namespace Dali
@@ -191,7 +191,7 @@ void FlexLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeas
   oss << "FlexLayout::OnMeasure  ";
   if( actor )
   {
-       oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " Layout direction:" << actor.GetProperty( Actor::Property::LAYOUT_DIRECTION ).Get<int>() << " ";
+    oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " Layout direction:" << actor.GetProperty( Actor::Property::LAYOUT_DIRECTION ).Get<int>() << " ";
   }
   oss << "widthMeasureSpec:" << widthMeasureSpec << " heightMeasureSpec:" << heightMeasureSpec << std::endl;
   DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() );
@@ -218,23 +218,23 @@ void FlexLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeas
 
   if( widthMeasureSpec.GetMode() == MeasureSpec::Mode::EXACTLY )
   {
-    width = widthMeasureSpec.GetSize();
+    width = widthMeasureSpec.GetSize().AsDecimal();
     YGNodeStyleSetWidth( mRoot, width );
   }
   else if( widthMeasureSpec.GetMode() == MeasureSpec::Mode::AT_MOST )
   {
-    width = widthMeasureSpec.GetSize();
+    width = widthMeasureSpec.GetSize().AsDecimal();
     YGNodeStyleSetMaxWidth( mRoot, width );
   }
 
-  if (heightMeasureSpec.GetMode() == MeasureSpec::Mode::EXACTLY)
+  if ( heightMeasureSpec.GetMode() == MeasureSpec::Mode::EXACTLY )
   {
-    height = heightMeasureSpec.GetSize();
+    height = heightMeasureSpec.GetSize().AsDecimal();
     YGNodeStyleSetHeight( mRoot, height );
   }
-  else if (widthMeasureSpec.GetMode() == MeasureSpec::Mode::AT_MOST)
+  else if ( heightMeasureSpec.GetMode() == MeasureSpec::Mode::AT_MOST )
   {
-    height = heightMeasureSpec.GetSize();
+    height = heightMeasureSpec.GetSize().AsDecimal();
     YGNodeStyleSetMaxHeight( mRoot, height );
   }
 
@@ -249,8 +249,8 @@ void FlexLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top, La
   auto owner = GetOwner();
   auto actor = Actor::DownCast(owner);
   bool isLayoutRtl = actor ? actor.GetProperty( Actor::Property::LAYOUT_DIRECTION ).Get<int>() == LayoutDirection::RIGHT_TO_LEFT: false;
-  auto width = right - left;
-  auto height = bottom - top;
+  LayoutLength width = right - left;
+  LayoutLength height = bottom - top;
 
 #if defined(DEBUG_ENABLED)
   std::ostringstream oss;
@@ -263,7 +263,7 @@ void FlexLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top, La
   DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() );
 #endif
 
-  YGNodeCalculateLayout( mRoot, width, height, isLayoutRtl ? YGDirectionRTL : YGDirectionLTR );
+  YGNodeCalculateLayout( mRoot, width.AsDecimal(), height.AsDecimal(), isLayoutRtl ? YGDirectionRTL : YGDirectionLTR );
 
   auto count = GetChildCount();
   for( unsigned int childIndex = 0; childIndex < count; childIndex++)
@@ -272,10 +272,10 @@ void FlexLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top, La
     if( childLayout != nullptr )
     {
       YGNodeRef node = YGNodeGetChild(mRoot, childIndex);
-      auto childLeft = YGNodeLayoutGetLeft( node ) + left;
-      auto childTop = YGNodeLayoutGetTop( node ) + top;
-      auto childWidth = YGNodeLayoutGetWidth( node );
-      auto childHeight = YGNodeLayoutGetHeight( node );
+      LayoutLength childLeft = LayoutLength( YGNodeLayoutGetLeft( node ) )+ left;
+      LayoutLength childTop = LayoutLength( YGNodeLayoutGetTop( node ) ) + top;
+      LayoutLength childWidth = LayoutLength( YGNodeLayoutGetWidth( node ) );
+      LayoutLength childHeight = LayoutLength( YGNodeLayoutGetHeight( node ) );
       childLayout->Layout( childLeft, childTop, childLeft + childWidth, childTop + childHeight );
     }
   }
@@ -290,66 +290,29 @@ YGSize FlexLayout::OnChildMeasure( YGNodeRef node,
   auto childOwner = childLayout->GetOwner();
   auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
   auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
-
-  MeasureSpec::Mode measureWidthMode = MeasureSpec::Mode::AT_MOST;
-  MeasureSpec::Mode measureHeightMode = MeasureSpec::Mode::AT_MOST;
-  if( desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT )
-  {
-    if( innerWidth != YGUndefined)
-    {
-      desiredWidth = innerWidth;
-    }
-    measureWidthMode = MeasureSpec::Mode::EXACTLY;
-  }
-
-  if( desiredHeight == Toolkit::ChildLayoutData::MATCH_PARENT )
+  MeasureSpec parentWidthMeasureSpec( 0 );
+  if ( innerWidth != YGUndefined )
   {
-    if( innerWidth != YGUndefined)
-    {
-      desiredHeight = innerHeight;
-    }
-    measureHeightMode = MeasureSpec::Mode::EXACTLY;
+    parentWidthMeasureSpec = MeasureSpec( innerWidth, static_cast<MeasureSpec::Mode>(widthMode) );
   }
-
-  if( desiredWidth == Toolkit::ChildLayoutData::WRAP_CONTENT )
+  auto parentHeightMeasureSpec = MeasureSpec( 0 );
+  if ( innerHeight != YGUndefined )
   {
-    measureWidthMode = MeasureSpec::Mode::UNSPECIFIED;
+    parentHeightMeasureSpec = MeasureSpec( innerHeight, static_cast<MeasureSpec::Mode>(heightMode) );
   }
+  auto childWidthMeasureSpec = LayoutGroup::GetChildMeasureSpec( parentWidthMeasureSpec, 0, desiredWidth);
+  auto childHeightMeasureSpec = LayoutGroup::GetChildMeasureSpec( parentHeightMeasureSpec, 0, desiredHeight);
 
-  if( desiredHeight == Toolkit::ChildLayoutData::WRAP_CONTENT )
+  // Force to fill parent if a child wants to match parent even if GetChildMeasureSpec sets otherwise
+  if( desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT && innerWidth != YGUndefined )
   {
-    measureHeightMode = MeasureSpec::Mode::UNSPECIFIED;
+    childWidthMeasureSpec = MeasureSpec( innerWidth, MeasureSpec::Mode::EXACTLY );
   }
-
-  MeasureSpec widthMeasureSpec = MeasureSpec( desiredWidth, measureWidthMode );
-  MeasureSpec heightMeasureSpec = MeasureSpec( desiredHeight, measureHeightMode );
-  if( measureWidthMode == MeasureSpec::Mode::UNSPECIFIED ||
-      measureHeightMode == MeasureSpec::Mode::UNSPECIFIED )
+  if( desiredHeight == Toolkit::ChildLayoutData::MATCH_PARENT && innerHeight != YGUndefined )
   {
-    // A measure just to get the size if the wrapped content
-    childLayout->Measure( widthMeasureSpec, heightMeasureSpec );
-    desiredWidth = childLayout->GetMeasuredWidth();
-    desiredHeight = childLayout->GetMeasuredHeight();
-    // Remove padding here since the second measure will add it back
-    Extents padding = childLayout->GetPadding();
-    desiredWidth = desiredWidth - padding.end - padding.start;
-    desiredHeight = desiredHeight - padding.bottom - padding.top;
+    childHeightMeasureSpec = MeasureSpec( innerHeight, MeasureSpec::Mode::EXACTLY );
   }
 
-  // Safety check to avoid going out of boundary
-  if( (innerWidth != YGUndefined && innerWidth != 0) && innerWidth < desiredWidth )
-  {
-    desiredWidth = innerWidth;
-  }
-
-  if( (innerHeight != YGUndefined && innerHeight != 0) && innerHeight < desiredHeight )
-  {
-    desiredHeight = innerHeight;
-  }
-
-  // Measure for Yoga
-  MeasureSpec ygWidthMeasureSpec = MeasureSpec( desiredWidth, static_cast<MeasureSpec::Mode>(widthMode) );
-  MeasureSpec ygHeightMeasureSpec = MeasureSpec( desiredHeight, static_cast<MeasureSpec::Mode>(heightMode) );
 #if defined(DEBUG_ENABLED)
   auto actor = Actor::DownCast(childOwner);
   std::ostringstream oss;
@@ -358,31 +321,25 @@ YGSize FlexLayout::OnChildMeasure( YGNodeRef node,
   {
     oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " ";
   }
-  oss << "innerWidth:" << ((innerWidth == YGUndefined) ? "YGUndefined " : "") << innerWidth <<
-         " innerHeight:" << ((innerHeight == YGUndefined) ? "YGUndefined " : "") << innerHeight <<
+  oss << "innerWidth:" << ( ( innerWidth == YGUndefined ) ? "YGUndefined " : "" ) << innerWidth <<
+         " innerHeight:" << ( ( innerHeight == YGUndefined ) ? "YGUndefined " : "" ) << innerHeight <<
          " desiredWidth:" << desiredWidth << " desiredHeight:" << desiredHeight <<
-         " widthMeasureSpec:" << widthMeasureSpec << " heightMeasureSpec:" << heightMeasureSpec <<
-         " ygWidthMeasureSpec:" << ygWidthMeasureSpec << " ygHeightMeasureSpec:" << ygHeightMeasureSpec << std::endl;
+         " childWidthMeasureSpec:" << childWidthMeasureSpec << " childHeightMeasureSpec:" << childHeightMeasureSpec << std::endl;
   DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() );
 #endif
 
-  if( measureWidthMode == MeasureSpec::Mode::UNSPECIFIED ||
-      measureHeightMode == MeasureSpec::Mode::UNSPECIFIED )
-  {
-    if( ygWidthMeasureSpec == widthMeasureSpec && ygHeightMeasureSpec == heightMeasureSpec )
-    {
-      return YGSize{
-        .width = childLayout->GetMeasuredWidth(),
-        .height = childLayout->GetMeasuredHeight(),
-      };
-    }
-  }
+  childLayout->Measure( childWidthMeasureSpec, childHeightMeasureSpec );
+
+  // Remove padding here since Yoga doesn't consider it as a part of the node size
+  Extents padding = childLayout->GetPadding();
+  LayoutLength measuredWidth = childLayout->GetMeasuredWidth() - padding.end - padding.start;
+  LayoutLength measuredHeight = childLayout->GetMeasuredHeight() - padding.bottom - padding.top;
 
-  childLayout->Measure( ygWidthMeasureSpec, ygHeightMeasureSpec );
-  return YGSize{
-    .width = childLayout->GetMeasuredWidth(),
-    .height = childLayout->GetMeasuredHeight(),
-  };
+  // Create struct instance first and manually set params to support all compiler versions
+  YGSize ygSize;
+  ygSize.width = measuredWidth.AsDecimal();
+  ygSize.height = measuredHeight.AsDecimal();
+  return ygSize;
 }
 
 void FlexLayout::SetChildrenStyle()