Quick fix of Popup after removing PropagateRelayoutFlags()
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / popup / popup-impl.cpp
index 83ea7eb..0a58b7c 100755 (executable)
 #include <dali-toolkit/internal/controls/popup/popup-impl.h>
 
 // EXTERNAL INCLUDES
+#include <cstring> // for strcmp
 #include <dali/public-api/adaptor-framework/key.h>
-#include <dali/public-api/adaptor-framework/physical-keyboard.h>
+#include <dali/devel-api/adaptor-framework/physical-keyboard.h>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/public-api/events/key-event.h>
 #include <dali/public-api/events/touch-event.h>
+#include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali/public-api/size-negotiation/relayout-container.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/buttons/button.h>
-#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
-#include <dali-toolkit/internal/controls/relayout-helper.h>
-#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
+#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
 #include <dali-toolkit/public-api/focus-manager/focus-manager.h>
+#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
+#include <dali-toolkit/internal/controls/buttons/button-impl.h>
 
 using namespace Dali;
 
-namespace
-{
-const float CONTENT_DEPTH = 1.0f;                                 ///< 3D Effect of buttons/title etc. appearing off the popup.
-const float POPUP_ANIMATION_DURATION = 0.5f;                      ///< Duration of hide/show animations
-const float BACKING_DEPTH = -1.0f;                                ///< Depth of backing (positioned just behind dialog, so dialog catches hit events first)
-
-const float POPUP_WIDTH = 720.0f;                             ///< Width of Popup
-const float POPUP_OUT_MARGIN_WIDTH = 16.f;                    ///< Space between the screen edge and the popup edge in the horizontal dimension.
-const float POPUP_OUT_MARGIN_HEIGHT = 36.f;                   ///< Space between the screen edge and the popup edge in the vertical dimension.
-const float POPUP_TITLE_WIDTH = 648.0f;                       ///<Width of Popup Title
-const float POPUP_BUTTON_BG_HEIGHT = 96.f;                    ///< Height of Button Background.
-const Vector3 DEFAULT_DIALOG_SIZE = Vector3(POPUP_TITLE_WIDTH/POPUP_WIDTH, 0.5f, 0.0f);
-const Vector3 DEFAULT_BOTTOM_SIZE = Vector3(1.0f, 0.2f, 0.0f);
-
-const char* const PROPERTY_TITLE = "title";
-const char* const PROPERTY_STATE = "state";
-
-/**
- * The background size should be at least as big as the Dialog.
- * In some cases a background may have graphics which are visible
- * outside of the Dialog, e.g. A Shadow. For this we need to alter
- * the size of Background.
- *
- * @param[in] outerBorder The border to extend beyond parent's Size.
- * @param[in] parentSize  The parent's size
- */
-Vector3 BackgroundSize(const Vector4& outerBoarder, const Vector3& parentSize)
-{
-  Vector3 size( parentSize );
-  size.width += outerBoarder.x + outerBoarder.y;
-  size.height += outerBoarder.z + outerBoarder.w;
-
-  return size;
-}
-
-  /**
-   * sets button area size to parent's size plus a border.
-   *
-   * @param[in] outerBorder The border to extend beyond parent's Size.
-   * @param[in] parentSize  The parent's size
-   */
-Vector3 ButtonAreaSize( const Vector4& outBoarder, const Vector3& parentSize )
-{
-  Vector3 size( parentSize );
-  size.width += outBoarder.x + outBoarder.y;
-  size.width -= (POPUP_OUT_MARGIN_WIDTH + POPUP_OUT_MARGIN_WIDTH);
-  size.height = POPUP_BUTTON_BG_HEIGHT;
-
-  return size;
-}
-
-} // unnamed namespace
-
 namespace Dali
 {
 
@@ -108,14 +59,29 @@ BaseHandle Create()
   return Toolkit::Popup::New();
 }
 
-TypeRegistration typeRegistration( typeid(Toolkit::Popup), typeid(Toolkit::Control), Create );
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Popup, Toolkit::Control, Create )
 
-SignalConnectorType signalConnector1( typeRegistration, Toolkit::Popup::SIGNAL_TOUCHED_OUTSIDE, &Popup::DoConnectSignal );
-SignalConnectorType signalConnector2( typeRegistration, Toolkit::Popup::SIGNAL_HIDDEN, &Popup::DoConnectSignal );
+DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "touched-outside", SIGNAL_TOUCHED_OUTSIDE )
+DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "hidden",          SIGNAL_HIDDEN          )
 
+DALI_TYPE_REGISTRATION_END()
 
-}
+// Properties
+const char* const PROPERTY_TITLE = "title";
+const char* const PROPERTY_STATE = "state";
+
+const float POPUP_ANIMATION_DURATION = 0.45f;                      ///< Duration of hide/show animations
+
+const float POPUP_WIDTH = 720.0f;                             ///< Width of Popup
+const float POPUP_OUT_MARGIN_WIDTH = 16.f;                    ///< Space between the screen edge and the popup edge in the horizontal dimension.
+const float POPUP_OUT_MARGIN_HEIGHT = 36.f;                   ///< Space between the screen edge and the popup edge in the vertical dimension.
+const float POPUP_TITLE_WIDTH = 648.0f;                       ///<Width of Popup Title
+const float POPUP_BUTTON_BG_HEIGHT = 96.f;                    ///< Height of Button Background.
+const Vector3 DEFAULT_DIALOG_SIZE = Vector3(POPUP_TITLE_WIDTH/POPUP_WIDTH, 0.5f, 0.0f);
+const Vector3 DEFAULT_BOTTOM_SIZE = Vector3(1.0f, 0.2f, 0.0f);
 
+} // unnamed namespace
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Popup
@@ -152,33 +118,49 @@ Popup::Popup(PopupStyle& style)
 
 void Popup::OnInitialize()
 {
+  Dali::Stage stage = Dali::Stage::GetCurrent();
+
   Actor self = Self();
   self.SetSensitive(false);
+  // Reisize to fit the height of children
+  self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT );
 
   // Create Layer
   mLayer = Layer::New();
+  mLayer.SetName( "POPUP_LAYER" );
   mLayer.SetParentOrigin(ParentOrigin::CENTER);
   mLayer.SetAnchorPoint(AnchorPoint::CENTER);
-  mLayer.RaiseToTop();
-  self.Add(mLayer);
-
-  mPopupBg = Actor::New();
-  mPopupBg.SetParentOrigin(ParentOrigin::CENTER);
-  mPopupBg.SetAnchorPoint(AnchorPoint::CENTER);
-  mLayer.Add(mPopupBg);
+  mLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  mLayer.SetDrawMode( DrawMode::OVERLAY );
 
   // Any content after this point which is added to Self() will be reparented to
   // mContent.
   mAlterAddedChild = true;
-
   // Add Backing (Dim effect)
   CreateBacking();
+  mAlterAddedChild = false;
 
   // Add Dialog ( background image, title, content container, button container and tail )
   CreateDialog();
 
+  mLayer.Add( self );
+
+  mPopupLayout = Toolkit::TableView::New( 3, 1 );
+  mPopupLayout.SetName( "POPUP_LAYOUT_TABLE" );
+  mPopupLayout.SetParentOrigin(ParentOrigin::CENTER);
+  mPopupLayout.SetAnchorPoint(AnchorPoint::CENTER);
+  mPopupLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
+  mPopupLayout.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
+  mPopupLayout.SetFitHeight( 0 );   // Set row to fit
+  mPopupLayout.SetFitHeight( 1 );   // Set row to fit
+  self.Add( mPopupLayout );
+
+  // Any content after this point which is added to Self() will be reparented to
+  // mContent.
+  mAlterAddedChild = true;
+
   // Default content.
-  ShowTail(ParentOrigin::BOTTOM_CENTER);
+//  ShowTail(ParentOrigin::BOTTOM_CENTER);
 
   // Hide content by default.
   SetState( Toolkit::Popup::POPUP_HIDE, 0.0f );
@@ -213,6 +195,7 @@ void Popup::OnPropertySet( Property::Index index, Property::Value propertyValue
 
 Popup::~Popup()
 {
+  mLayer.Unparent();
 }
 
 size_t Popup::GetButtonCount() const
@@ -223,26 +206,38 @@ size_t Popup::GetButtonCount() const
 void Popup::SetBackgroundImage( Actor image )
 {
   // Removes any previous background.
-  if( mBackgroundImage && mPopupBg )
+  if( mBackgroundImage && mPopupLayout )
   {
-    mPopupBg.Remove( mBackgroundImage );
+    mPopupLayout.Remove( mBackgroundImage );
   }
 
   // Adds new background to the dialog.
   mBackgroundImage = image;
 
+  mBackgroundImage.SetName( "POPUP_BACKGROUND_IMAGE" );
+
   // OnDialogTouched only consume the event. It prevents the touch event to be caught by the backing.
   mBackgroundImage.TouchedSignal().Connect( this, &Popup::OnDialogTouched );
 
-  mPopupBg.Add( mBackgroundImage );
+  mBackgroundImage.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
+  mBackgroundImage.SetAnchorPoint( AnchorPoint::CENTER );
+  mBackgroundImage.SetParentOrigin( ParentOrigin::CENTER );
+
+  Vector3 border( mPopupStyle->backgroundOuterBorder.x, mPopupStyle->backgroundOuterBorder.z, 0.0f );
+  mBackgroundImage.SetSizeModeFactor( border );
+
+  const bool prevAlter = mAlterAddedChild;
+  mAlterAddedChild = false;
+  Self().Add( mBackgroundImage );
+  mAlterAddedChild = prevAlter;
 }
 
 void Popup::SetButtonAreaImage( Actor image )
 {
   // Removes any previous area image.
-  if( mButtonAreaImage && mPopupBg )
+  if( mButtonAreaImage && mPopupLayout )
   {
-    mPopupBg.Remove( mButtonAreaImage );
+    mPopupLayout.Remove( mButtonAreaImage );
   }
 
   // Adds new area image to the dialog.
@@ -251,43 +246,80 @@ void Popup::SetButtonAreaImage( Actor image )
   // OnDialogTouched only consume the event. It prevents the touch event to be caught by the backing.
   mButtonAreaImage.TouchedSignal().Connect( this, &Popup::OnDialogTouched );
 
-  mPopupBg.Add( mButtonAreaImage );
+  mButtonAreaImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  mButtonAreaImage.SetAnchorPoint( AnchorPoint::CENTER );
+  mButtonAreaImage.SetParentOrigin( ParentOrigin::CENTER );
+
+  if( GetButtonCount() > 0 )
+  {
+    mBottomBg.Add( mButtonAreaImage );
+  }
 }
 
 void Popup::SetTitle( const std::string& text )
 {
-  Toolkit::TextView titleActor = Toolkit::TextView::New();
-  titleActor.SetText( text );
-  titleActor.SetColor( Color::BLACK );
-  titleActor.SetMultilinePolicy( Toolkit::TextView::SplitByWord );
-  titleActor.SetWidthExceedPolicy( Toolkit::TextView::Split );
-  titleActor.SetLineJustification( Toolkit::TextView::Center );
+  // Replaces the current title actor.
+  if( mPopupLayout )
+  {
+    mPopupLayout.RemoveChildAt( Toolkit::TableView::CellPosition( 0, 0 ) );
+  }
+
+  mTitle = Toolkit::TextLabel::New( text );
+  mTitle.SetName( "POPUP_TITLE" );
+  mTitle.SetProperty( Toolkit::TextLabel::Property::MULTI_LINE, true );
+  mTitle.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+
+  if( mPopupLayout )
+  {
+    mTitle.SetPadding( Padding( 0.0f, 0.0f, mPopupStyle->margin, mPopupStyle->margin ) );
+    mTitle.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
+    mTitle.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
+    mPopupLayout.AddChild( mTitle, Toolkit::TableView::CellPosition( 0, 0 ) );
+  }
 
-  SetTitle( titleActor );
+  RelayoutRequest();
 }
 
-void Popup::SetTitle( Toolkit::TextView titleActor )
+std::string Popup::GetTitle() const
 {
-  // Replaces the current title actor.
-  if( mTitle && mPopupBg )
+  if( mTitle )
   {
-    mPopupBg.Remove( mTitle );
+    return mTitle.GetProperty<std::string>( Toolkit::TextLabel::Property::TEXT );
   }
-  mTitle = titleActor;
 
-  mPopupBg.Add( mTitle );
-
-  RelayoutRequest();
+  return std::string();
 }
 
-Toolkit::TextView Popup::GetTitle() const
+void Popup::CreateFooter()
 {
-  return mTitle;
+  if( !mBottomBg )
+  {
+    // Adds bottom background
+    mBottomBg = Actor::New();
+    mBottomBg.SetName( "POPUP_BOTTOM_BG" );
+    mBottomBg.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+
+    mPopupLayout.SetFixedHeight( 2, mPopupStyle->bottomSize.height );   // Buttons
+    mPopupLayout.AddChild( mBottomBg, Toolkit::TableView::CellPosition( 2, 0 ) );
+  }
 }
 
 void Popup::AddButton( Toolkit::Button button )
 {
   mButtons.push_back( button );
+  button.SetResizePolicy( ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS );    // Size will be assigned to it
+
+  // If this is the first button added
+  if( mButtons.size() == 1 )
+  {
+    CreateFooter();
+
+    if( mButtonAreaImage )
+    {
+      mBottomBg.Add( mButtonAreaImage );
+    }
+  }
+
   mBottomBg.Add( button );
 
   RelayoutRequest();
@@ -340,13 +372,15 @@ void Popup::ShowTail(const Vector3& position)
 
   if(image != "")
   {
-    Image tail = Image::New( image );
+    Image tail = ResourceImage::New( image );
     mTailImage = ImageActor::New(tail);
-    const Vector3 anchorPoint = AnchorPoint::FRONT_BOTTOM_RIGHT - position;
+    const Vector3 anchorPoint = AnchorPoint::BOTTOM_RIGHT - position;
 
     mTailImage.SetParentOrigin(position);
     mTailImage.SetAnchorPoint(anchorPoint);
 
+    CreateFooter();
+
     mBottomBg.Add(mTailImage);
   }
 }
@@ -369,30 +403,25 @@ PopupStylePtr Popup::GetStyle() const
 
 void Popup::SetDefaultBackgroundImage()
 {
-  Image bg = Image::New( mPopupStyle->backgroundImage );
-  ImageActor bgImage = ImageActor::New( bg );
-  bgImage.SetStyle( ImageActor::STYLE_NINE_PATCH );
-  bgImage.SetNinePatchBorder( mPopupStyle->backgroundScale9Border );
-
-  Image buttonBg = Image::New( mPopupStyle->buttonAreaImage );
+  Image buttonBg = ResourceImage::New( mPopupStyle->buttonAreaImage );
   ImageActor buttonBgImage = ImageActor::New( buttonBg );
   buttonBgImage.SetStyle( ImageActor::STYLE_NINE_PATCH );
   buttonBgImage.SetNinePatchBorder( mPopupStyle->buttonArea9PatchBorder );
 
-  SetBackgroundImage( bgImage );
+  SetBackgroundImage( ImageActor::New( ResourceImage::New( mPopupStyle->backgroundImage ) ) );
   SetButtonAreaImage( buttonBgImage );
 }
 
 void Popup::CreateBacking()
 {
   mBacking = Dali::Toolkit::CreateSolidColorActor( mPopupStyle->backingColor );
+  mBacking.SetName( "POPUP_BACKING" );
 
-  mBacking.SetPositionInheritanceMode(DONT_INHERIT_POSITION);
+  mBacking.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
   mBacking.SetSensitive(true);
 
-  mLayer.Add(mBacking);
+  mLayer.Add( mBacking );
   mBacking.SetOpacity(0.0f);
-  mBacking.SetPosition(0.0f, 0.0f, BACKING_DEPTH);
   mBacking.TouchedSignal().Connect( this, &Popup::OnBackingTouched );
   mBacking.MouseWheelEventSignal().Connect(this, &Popup::OnBackingMouseWheelEvent);
 }
@@ -401,19 +430,12 @@ void Popup::CreateDialog()
 {
   // Adds default background image.
   SetDefaultBackgroundImage();
-
-  // Adds bottom background
-  mBottomBg = Actor::New();
-  mPopupBg.Add( mBottomBg );
 }
 
 void Popup::HandleStateChange( Toolkit::Popup::PopupState state, float duration )
 {
-  const Vector2& stageSize( Stage::GetCurrent().GetSize() );
-
   Vector3 targetSize;
   float targetBackingAlpha;
-  Vector3 targetBackingSize;
 
   if(mState == state)
   {
@@ -426,7 +448,6 @@ void Popup::HandleStateChange( Toolkit::Popup::PopupState state, float duration
     {
       targetSize = Vector3(0.0f, 0.0f, 1.0f);
       targetBackingAlpha = 0.0f;
-      targetBackingSize = Vector3(0.0f, 0.0f, 1.0f);
       mShowing = false;
       ClearKeyInputFocus();
 
@@ -448,17 +469,16 @@ void Popup::HandleStateChange( Toolkit::Popup::PopupState state, float duration
     {
       targetSize = Vector3(1.0f, 1.0f, 1.0f);
       targetBackingAlpha = 1.0f;
-      float length = (stageSize.width > stageSize.height) ? stageSize.width : stageSize.height;
-      targetBackingSize = Vector3( length, length, 1.0f );
       mShowing = true;
 
       // Add contents to stage for showing.
       if( !mLayer.GetParent() )
       {
-        mAlterAddedChild = false;
-        Self().Add(mLayer);
-        mAlterAddedChild = true;
+        Dali::Stage stage = Dali::Stage::GetCurrent();
+        stage.Add( mLayer );
+        mLayer.RaiseToTop();
       }
+
       Self().SetSensitive(true);
       SetKeyInputFocus();
 
@@ -487,8 +507,7 @@ void Popup::HandleStateChange( Toolkit::Popup::PopupState state, float duration
     }
   }
 
-  mBacking.SetSize( targetBackingSize );
-
+  Actor self = Self();
   if(duration > Math::MACHINE_EPSILON_1)
   {
     if ( mAnimation )
@@ -501,13 +520,13 @@ void Popup::HandleStateChange( Toolkit::Popup::PopupState state, float duration
 
     if(mShowing)
     {
-      mAnimation.AnimateTo( Property(mBacking, Actor::COLOR_ALPHA), targetBackingAlpha, AlphaFunctions::EaseInOut, TimePeriod(0.0f, duration * 0.5f) );
-      mAnimation.AnimateTo( Property(mPopupBg, Actor::SCALE), targetSize, AlphaFunctions::EaseInOut, TimePeriod(duration * 0.5f, duration * 0.5f) );
+      mAnimation.AnimateTo( Property(mBacking, Actor::Property::COLOR_ALPHA), targetBackingAlpha, AlphaFunction::EASE_IN_OUT, TimePeriod(0.0f, duration * 0.5f) );
+      mAnimation.AnimateTo( Property(self, Actor::Property::SCALE), targetSize, AlphaFunction::EASE_IN_OUT, TimePeriod(duration * 0.5f, duration * 0.5f) );
     }
     else
     {
-      mAnimation.AnimateTo( Property(mBacking, Actor::COLOR_ALPHA), targetBackingAlpha, AlphaFunctions::EaseInOut, TimePeriod(0.0f, duration * 0.5f) );
-      mAnimation.AnimateTo( Property(mPopupBg, Actor::SCALE), targetSize, AlphaFunctions::EaseInOut, TimePeriod(0.0f, duration * 0.5f) );
+      mAnimation.AnimateTo( Property(mBacking, Actor::Property::COLOR_ALPHA), targetBackingAlpha, AlphaFunction::EASE_IN_OUT, TimePeriod(0.0f, duration * 0.5f) );
+      mAnimation.AnimateTo( Property(self, Actor::Property::SCALE), targetSize, AlphaFunction::EASE_IN_OUT, TimePeriod(0.0f, duration * 0.5f) );
     }
     mAnimation.Play();
     mAnimation.FinishedSignal().Connect(this, &Popup::OnStateAnimationFinished);
@@ -515,7 +534,7 @@ void Popup::HandleStateChange( Toolkit::Popup::PopupState state, float duration
   else
   {
     mBacking.SetOpacity( targetBackingAlpha );
-    mPopupBg.SetScale( targetSize );
+    self.SetScale( targetSize );
 
     HandleStateChangeComplete();
   }
@@ -524,9 +543,9 @@ void Popup::HandleStateChange( Toolkit::Popup::PopupState state, float duration
 void Popup::HandleStateChangeComplete()
 {
   // Remove contents from stage if completely hidden.
-  if( (mState == Toolkit::Popup::POPUP_HIDE) && (mLayer.GetParent()) )
+  if( ( mState == Toolkit::Popup::POPUP_HIDE ) && mLayer.GetParent() )
   {
-    Self().Remove(mLayer);
+    mLayer.Unparent();
     Self().SetSensitive( false );
 
     // Guard against destruction during signal emission
@@ -550,13 +569,13 @@ bool Popup::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
   Dali::BaseHandle handle( object );
 
   bool connected( true );
-  Toolkit::Popup popup = Toolkit::Popup::DownCast(handle);
+  Toolkit::Popup popup = Toolkit::Popup::DownCast( handle );
 
-  if( Dali::Toolkit::Popup::SIGNAL_TOUCHED_OUTSIDE == signalName )
+  if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED_OUTSIDE ) )
   {
     popup.OutsideTouchedSignal().Connect( tracker, functor );
   }
-  else if( Dali::Toolkit::Popup::SIGNAL_HIDDEN == signalName )
+  else if( 0 == strcmp( signalName.c_str(), SIGNAL_HIDDEN ) )
   {
     popup.HiddenSignal().Connect( tracker, functor );
   }
@@ -612,169 +631,78 @@ void Popup::OnControlChildAdd( Actor& child )
     // Removes previously added content.
     if( mContent )
     {
-      mPopupBg.Remove( mContent );
+      mPopupLayout.RemoveChildAt( Toolkit::TableView::CellPosition( 1, 0 ) );
     }
 
-    // Reparent new content.
-    Self().Remove( child );
-
     // keep a handle to the new content.
     mContent = child;
 
-    mPopupBg.Add( mContent );
+    mPopupLayout.AddChild( mContent, Toolkit::TableView::CellPosition( 1, 0 ) );
   }
 }
 
-void Popup::OnControlSizeSet( const Vector3& targetSize )
+void Popup::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
-  mLayer.SetSize( targetSize );
-  mPopupBg.SetSize( targetSize );
-
-  const Vector4 outerBorder = mPopupStyle->backgroundOuterBorder;
-  if( mBackgroundImage )
-  {
-    mBackgroundImage.SetSize( BackgroundSize( outerBorder,targetSize ) );
-  }
-  if( mButtonAreaImage )
-  {
-    mButtonAreaImage.SetSize( ButtonAreaSize( outerBorder, targetSize ) );
-  }
-
-}
-
-void Popup::OnRelayout( const Vector2& size, ActorSizeContainer& container )
-{
-  // Set the popup size
-  Vector2 popupSize;
-  popupSize.width  = size.width - 2.f * ( POPUP_OUT_MARGIN_WIDTH + mPopupStyle->margin );
-  popupSize.height = size.height - 2.f * ( POPUP_OUT_MARGIN_WIDTH + mPopupStyle->margin );
-
-  // Update sizes of all popup's components.
-
-  // Relayout background image.
-  // Adjust background position and size relative to parent to cater to outer Border.
-  // Some backgrounds are intended to over-spill. That is some content
-  // should appear outside the Dialog on all sides i.e. Shadows, glow effects.
-  const Vector4 outerBorder = mPopupStyle->backgroundOuterBorder;
-
-  if( mBackgroundImage )
-  {
-    mBackgroundImage.SetSize(BackgroundSize(outerBorder, Vector3(size)));
-    mBackgroundImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-    mBackgroundImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
-    mBackgroundImage.SetPosition( -outerBorder.x, -outerBorder.y, 0.0f );
-  }
-
-  if( mPopupBg && mButtonAreaImage )
-  {
-    // If there are no buttons, button background is also removed.
-    if ( mButtons.size() == 0 )
-    {
-      mPopupBg.Remove( mButtonAreaImage );
-    }
-    else
-    {
-      mButtonAreaImage.SetSize( ButtonAreaSize(outerBorder, Vector3(size)) );
-      mButtonAreaImage.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
-      mButtonAreaImage.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
-      mButtonAreaImage.SetY( -outerBorder.z - POPUP_OUT_MARGIN_HEIGHT );
-
-      mPopupBg.Add( mButtonAreaImage );
-    }
-  }
-
-  // Relayout title
-  Vector3 positionOffset( 0.0f, mPopupStyle->margin + POPUP_OUT_MARGIN_WIDTH, CONTENT_DEPTH );
-  if( mTitle )
-  {
-    Vector2 titleSize;
-    titleSize.width  = popupSize.width;
-    titleSize.height = mTitle.GetHeightForWidth( titleSize.width );
-
-    // As the default size policy for text-view is Fixed & Fixed, a size needs to be set.
-    // Otherwise size-negotiation algorithm uses the GetNaturalSize() with doesn't take
-    // into account the multiline and exceed policies, giving as result a wrong size.
-    mTitle.SetSize( titleSize );
-    Relayout( mTitle, titleSize, container );
-
-    mTitle.SetAnchorPoint( AnchorPoint::TOP_CENTER );
-    mTitle.SetParentOrigin( ParentOrigin::TOP_CENTER );
-    mTitle.SetPosition( positionOffset );
-
-    positionOffset.y += titleSize.height + mPopupStyle->margin;
-  }
-
-  // Relayout content
-  if( mContent )
-  {
-    // If the content width is greater than popup width then scale it down/wrap text as needed
-    Vector2 contentSize( RelayoutHelper::GetNaturalSize( mContent ) );
-    if( contentSize.width > popupSize.width )
-    {
-      contentSize.width = popupSize.width;
-      contentSize.height = RelayoutHelper::GetHeightForWidth( mContent, contentSize.width );
-    }
-
-    mContent.SetSize( contentSize );
-    Relayout( mContent, contentSize, container );
-
-    mContent.SetParentOrigin(ParentOrigin::TOP_CENTER);
-    mContent.SetAnchorPoint(AnchorPoint::TOP_CENTER);
-
-    mContent.SetPosition( positionOffset );
-
-    positionOffset.y += contentSize.height + mPopupStyle->margin;
-  }
-
-  // Relayout Button Area
-  if( mBottomBg )
-  {
-    mBottomBg.SetSize( popupSize.width, mPopupStyle->bottomSize.height );
-
-    mBottomBg.SetParentOrigin(ParentOrigin::TOP_CENTER);
-    mBottomBg.SetAnchorPoint(AnchorPoint::TOP_CENTER);
-
-    mBottomBg.SetPosition( positionOffset );
-  }
+  // Hide the background image
+  mBackgroundImage.SetVisible( !( mButtons.empty() && mPopupLayout.GetChildCount() == 0 ) );
 
   // Relayout All buttons
-  if ( !mButtons.empty() )
+  if( !mButtons.empty() )
   {
     // All buttons should be the same size and fill the button area. The button spacing needs to be accounted for as well.
-    Vector2 buttonSize( ( ( popupSize.width - mPopupStyle->buttonSpacing * ( mButtons.size() - 1 ) ) / mButtons.size() ),
+    Vector2 buttonSize( ( ( size.width - mPopupStyle->buttonSpacing * ( mButtons.size() + 1 ) ) / mButtons.size() ),
                         mPopupStyle->bottomSize.height - mPopupStyle->margin );
 
-    Vector3 buttonPosition;
+    Vector3 buttonPosition( mPopupStyle->buttonSpacing, 0.0f, 0.0f );
 
-    for ( ActorIter iter = mButtons.begin(), endIter = mButtons.end();
+    for( std::vector< Actor >::iterator iter = mButtons.begin(), endIter = mButtons.end();
           iter != endIter;
           ++iter, buttonPosition.x += mPopupStyle->buttonSpacing + buttonSize.width )
     {
-      iter->SetPosition( buttonPosition );
+      Actor button = *iter;
 
       // If there is only one button, it needs to be laid out on center.
       if ( mButtons.size() == 1 )
       {
-        iter->SetAnchorPoint( AnchorPoint::CENTER );
-        iter->SetParentOrigin( ParentOrigin::CENTER );
+        buttonPosition.x = 0.0f;
+        button.SetAnchorPoint( AnchorPoint::CENTER );
+        button.SetParentOrigin( ParentOrigin::CENTER );
       }
       else
       {
-        iter->SetAnchorPoint( AnchorPoint::CENTER_LEFT );
-        iter->SetParentOrigin( ParentOrigin::CENTER_LEFT );
+        button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+        button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
       }
 
-      Relayout( *iter, buttonSize, container );
+      button.SetPosition( buttonPosition );
+
+     //Todo: Use the size negotiation pass instead of SetSize directly
+     button.SetSize( buttonSize );
     }
   }
+}
 
-  if( mShowing && mBacking )
+void Popup::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
+{
+  if( mPopupLayout )
   {
-    Vector2 stageSize = Stage::GetCurrent().GetSize();
-    float length = (stageSize.width > stageSize.height) ? stageSize.width : stageSize.height;
-    Vector3 targetBackingSize = Vector3( length, length, 1.0f );
-
-    mBacking.SetSize( targetBackingSize );
+    if( policy == ResizePolicy::FIT_TO_CHILDREN )
+    {
+      mPopupLayout.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, dimension );
+      if( dimension & Dimension::HEIGHT )
+      {
+        mPopupLayout.SetFitHeight( 1 );
+      }
+    }
+    else
+    {
+      mPopupLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, dimension );
+      // Make the content cell fill the whole of the available space
+      if( dimension & Dimension::HEIGHT )
+      {
+        mPopupLayout.SetRelativeHeight( 1, 1.0f );
+      }
+    }
   }
 }
 
@@ -809,7 +737,7 @@ Vector3 Popup::GetNaturalSize()
     const float titleBuffer = 0.5f;
     titleNaturalSize.width += titleBuffer;
 
-    // As TextView GetNaturalSize does not take wrapping into account, limit the width
+    // As TextLabel GetNaturalSize does not take wrapping into account, limit the width
     // to that of the stage
     if( titleNaturalSize.width >= maxWidth)
     {
@@ -826,13 +754,13 @@ Vector3 Popup::GetNaturalSize()
 
   if( mContent )
   {
-    Vector3 contentSize = RelayoutHelper::GetNaturalSize( mContent );
+    Vector3 contentSize = mContent.GetNaturalSize();
     // Choose the biggest width
     naturalSize.width = std::max( naturalSize.width, contentSize.width );
     if( naturalSize.width > maxWidth )
     {
       naturalSize.width = maxWidth;
-      contentSize.height = RelayoutHelper::GetHeightForWidth( mContent, maxWidth );
+      contentSize.height = mContent.GetHeightForWidth( maxWidth );
     }
     naturalSize.height += contentSize.height + mPopupStyle->margin;
   }
@@ -862,7 +790,7 @@ float Popup::GetHeightForWidth( float width )
 
   if( mContent )
   {
-    height += RelayoutHelper::GetHeightForWidth( mContent, popupWidth ) + mPopupStyle->margin;
+    height += mContent.GetHeightForWidth( popupWidth ) + mPopupStyle->margin;
   }
 
   if( !mButtons.empty() )
@@ -905,7 +833,7 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
   else
   {
     // Rebuild the focus chain because button or content can be added or removed dynamically
-    ActorContainer focusableActors;
+    std::vector< Actor > focusableActors;
     if( mContent && mContent.IsKeyboardFocusable() )
     {
       focusableActors.push_back(mContent);
@@ -919,7 +847,7 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
       }
     }
 
-    for ( ActorContainer::iterator iter = focusableActors.begin(), end = focusableActors.end(); iter != end; ++iter )
+    for( std::vector< Actor >::iterator iter = focusableActors.begin(), end = focusableActors.end(); iter != end; ++iter )
     {
       if ( currentFocusedActor == *iter )
       {