Setting layout already in use
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / control / control-data-impl.cpp
index 73769c8..a8387ee 100755 (executable)
@@ -36,6 +36,8 @@
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
+#include <dali-toolkit/devel-api/layouting/bin-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 
@@ -67,6 +69,7 @@ namespace
 
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
+Debug::Filter* gLogFilterLayout = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT");
 #endif
 
 
@@ -339,7 +342,8 @@ Control::Impl::Impl( Control& controlImpl )
   mInputMethodContext(),
   mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
   mIsKeyboardNavigationSupported( false ),
-  mIsKeyboardFocusGroup( false )
+  mIsKeyboardFocusGroup( false ),
+  mIsLayoutingRequired( false )
 {
 }
 
@@ -1391,6 +1395,9 @@ void Control::Impl::OnStageDisconnection()
 void Control::Impl::SetMargin( Extents margin )
 {
   mControlImpl.mImpl->mMargin = margin;
+
+  // Trigger a size negotiation request that may be needed when setting a margin.
+  mControlImpl.RelayoutRequest();
 }
 
 Extents Control::Impl::GetMargin() const
@@ -1401,6 +1408,9 @@ Extents Control::Impl::GetMargin() const
 void Control::Impl::SetPadding( Extents padding )
 {
   mControlImpl.mImpl->mPadding = padding;
+
+  // Trigger a size negotiation request that may be needed when setting a padding.
+  mControlImpl.RelayoutRequest();
 }
 
 Extents Control::Impl::GetPadding() const
@@ -1431,17 +1441,60 @@ Toolkit::Internal::LayoutItemPtr Control::Impl::GetLayout() const
 
 void Control::Impl::SetLayout( Toolkit::Internal::LayoutItem& layout )
 {
+  DALI_LOG_INFO( gLogFilterLayout, Debug::Verbose, "Control::SetLayout control:%s  replacing existing layout:%s\n",
+                                   mControlImpl.Self().GetName().c_str(),
+                                   mLayout?"true":"false" );
+  // Check if layout already has an owner.
+  auto control = Toolkit::Control::DownCast( layout.GetOwner() );
+  if ( control )
+  {
+    // If the owner is not this control then the owning control can no longer own it.
+    Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
+    if( control != handle )
+    {
+      DALI_LOG_INFO( gLogFilterLayout, Debug::Verbose, "Control::SetLayout Layout already in use, %s will now have a BinLayout\n",
+                                                        control.GetName().c_str() );
+      Toolkit::BinLayout binLayout = Toolkit::BinLayout::New();
+      // Previous owner of the layout gets a BinLayout instead of the layout.
+      DevelControl::SetLayout( control, binLayout ) ;
+    }
+    else
+    {
+      return; // layout is already set to this control.
+    }
+  }
+
   if( mLayout )
   {
     mLayout->Unparent();
     mLayout.Reset();
   }
+
   mLayout = &layout;
 
   auto controlHandle = Toolkit::Control::DownCast( mControlImpl.Self() ); // Get a handle of this control implementation without copying internals.
   mLayout->Initialize( controlHandle, controlHandle.GetTypeName() ); // LayoutGroup takes ownership of existing children
 }
 
+void Control::Impl::RemoveLayout()
+{
+  DALI_LOG_INFO( gLogFilterLayout, Debug::Verbose, "Control::Impl::RemoveLayout\n");
+
+  Toolkit::BinLayout binLayout = Toolkit::BinLayout::New();
+
+  mControlImpl.mImpl->SetLayout( GetImplementation( binLayout ) ) ;
+}
+
+void Control::Impl::SetLayoutingRequired( bool layoutingRequired )
+{
+  mControlImpl.mImpl->mIsLayoutingRequired = layoutingRequired;
+}
+
+bool Control::Impl::IsLayoutingRequired()
+{
+  return mControlImpl.mImpl->mIsLayoutingRequired;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit