Automatically dis/connect registered visuals to stage 90/84390/16
authorXiangyin Ma <x1.ma@samsung.com>
Wed, 17 Aug 2016 13:47:51 +0000 (14:47 +0100)
committerXiangyin Ma <x1.ma@samsung.com>
Thu, 8 Sep 2016 12:55:06 +0000 (13:55 +0100)
Change-Id: Ia4808935cb603f107e0e40dc2a573e611cdb83e5

28 files changed:
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
dali-toolkit/devel-api/visual-factory/visual-base.h
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.h
dali-toolkit/internal/visuals/border/border-visual.cpp
dali-toolkit/internal/visuals/border/border-visual.h
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.h
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient-visual.h
dali-toolkit/internal/visuals/image/batch-image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/mesh/mesh-visual.cpp
dali-toolkit/internal/visuals/mesh/mesh-visual.h
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.h
dali-toolkit/internal/visuals/primitive/primitive-visual.cpp
dali-toolkit/internal/visuals/primitive/primitive-visual.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/internal/visuals/wireframe/wireframe-visual.cpp
dali-toolkit/internal/visuals/wireframe/wireframe-visual.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h

index fe4c588..b3c6795 100644 (file)
@@ -1117,7 +1117,8 @@ int UtcDaliVisualFactoryGetSvgVisual(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  // renderer is not added to actor until the rasterization is completed.
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
 
   EventThreadCallback* eventTrigger = EventThreadCallback::Get();
   CallbackBase* callback = eventTrigger->GetCallback();
@@ -1125,6 +1126,7 @@ int UtcDaliVisualFactoryGetSvgVisual(void)
   eventTrigger->WaitingForTrigger( 1 );// waiting until the svg image is rasterized.
   CallbackBase::Execute( *callback );
 
+  // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
 
   // waiting for the resource uploading
index 40864e5..74ca640 100644 (file)
@@ -116,7 +116,7 @@ public:
   float GetDepthIndex() const;
 
   /**
-   * @brief Visual needs to know when when the control is put on to the stage to add the renderer.
+   * @brief Visual needs to know when the control is put on to the stage to add the renderer.
    *
    * This function should be called when the control is put on to the stage.
    *
@@ -126,7 +126,7 @@ public:
   void SetOnStage( Actor& actor );
 
   /**
-   * @brief Visual needs to know when when the control is removed from the stage to remove the renderer.
+   * @brief Visual needs to know when the control is removed from the stage to remove the renderer.
    *
    * This function should be called when the control is removed from the stage
    *
index 53ccf41..9bf32ef 100644 (file)
@@ -576,7 +576,6 @@ void Button::SetColor( const Vector4& color, Button::PaintState selectedState )
       visual = visualFactory.CreateVisual( map );
 
       RegisterVisual( visualIndex, placementActor, visual );
-      visual.SetOnStage( placementActor );
 
       SetupContent( *contentActor, placementActor ); //
       contentActor->SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
index 7962e2e..251e317 100644 (file)
@@ -82,7 +82,8 @@ void ImageView::SetImage( Image image )
     mImage = image;
 
     Actor self( Self() );
-    InitializeVisual( self, mVisual, image );
+    mVisual =  Toolkit::VisualFactory::Get().CreateVisual( image );
+    RegisterVisual( Toolkit::ImageView::Property::IMAGE, self, mVisual  );
     mImageSize = image ? ImageDimensions( image.GetWidth(), image.GetHeight() ) : ImageDimensions( 0, 0 );
 
     RelayoutRequest();
@@ -96,7 +97,8 @@ void ImageView::SetImage( Property::Map map )
   mPropertyMap = map;
 
   Actor self( Self() );
-  InitializeVisual( self, mVisual, mPropertyMap );
+  mVisual =  Toolkit::VisualFactory::Get().CreateVisual( mPropertyMap );
+  RegisterVisual( Toolkit::ImageView::Property::IMAGE, self, mVisual  );
 
   Property::Value* widthValue = mPropertyMap.Find( "width" );
   if( widthValue )
@@ -138,7 +140,8 @@ void ImageView::SetImage( const std::string& url, ImageDimensions size )
     }
 
     Actor self( Self() );
-    InitializeVisual( self, mVisual, url, size );
+    mVisual =  Toolkit::VisualFactory::Get().CreateVisual( url, size );
+    RegisterVisual( Toolkit::ImageView::Property::IMAGE, self, mVisual  );
 
     mVisual.SetSize( mSizeSet );
 
@@ -231,28 +234,6 @@ float ImageView::GetWidthForHeight( float height )
 // Private methods
 //
 
-void ImageView::OnStageConnection( int depth )
-{
-  Control::OnStageConnection( depth );
-
-  if( mVisual )
-  {
-    CustomActor self = Self();
-    mVisual.SetOnStage( self );
-  }
-}
-
-void ImageView::OnStageDisconnection()
-{
-  if( mVisual )
-  {
-    CustomActor self = Self();
-    mVisual.SetOffStage( self );
-  }
-
-  Control::OnStageDisconnection();
-}
-
 void ImageView::OnSizeSet( const Vector3& targetSize )
 {
   Control::OnSizeSet( targetSize );
index 669a84f..f4f38b6 100644 (file)
@@ -123,16 +123,6 @@ public:
 private: // From Control
 
   /**
-   * @copydoc Toolkit::Control::OnStageConnect()
-   */
-  virtual void OnStageConnection( int depth );
-
-  /**
-   * @copydoc Toolkit::Control::OnStageDisconnection()
-   */
-  virtual void OnStageDisconnection();
-
-  /**
    * @copydoc Toolkit::Control::OnSizeSet()
    */
   virtual void OnSizeSet( const Vector3& targetSize );
index f5d8053..7f7c7b5 100644 (file)
@@ -147,6 +147,8 @@ void BorderVisual::DoSetOnStage( Actor& actor )
     mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
   }
   mBorderSizeIndex = (mImpl->mRenderer).RegisterProperty( Toolkit::BorderVisual::Property::SIZE, SIZE_NAME, mBorderSize );
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void BorderVisual::DoCreatePropertyMap( Property::Map& map ) const
index b7ca048..8a44250 100644 (file)
@@ -64,17 +64,17 @@ public:
 protected:
 
   /**
-   * @copydoc Visual::DoInitialize
+   * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
index 572220b..6406bcc 100644 (file)
@@ -94,6 +94,8 @@ void ColorVisual::SetSize( const Vector2& size )
 void ColorVisual::DoSetOnStage( Actor& actor )
 {
   InitializeRenderer();
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void ColorVisual::DoCreatePropertyMap( Property::Map& map ) const
index 9367ffa..2805d6a 100644 (file)
@@ -58,24 +58,24 @@ public:
 public:  // from Visual
 
   /**
-   * @copydoc Visual::SetSize
+   * @copydoc Visual::Base::SetSize
    */
   virtual void SetSize( const Vector2& size );
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
 
   /**
-   * @copydoc Visual::DoInitialize
+   * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
index 1588b83..41999cc 100644 (file)
@@ -232,6 +232,8 @@ void GradientVisual::SetSize( const Vector2& size )
 void GradientVisual::DoSetOnStage( Actor& actor )
 {
   InitializeRenderer();
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void GradientVisual::DoCreatePropertyMap( Property::Map& map ) const
index 9f2cad4..2f5d06c 100644 (file)
@@ -94,23 +94,23 @@ public:
 public:  // from Visual
 
   /**
-   * @copydoc Visual::SetSize
+   * @copydoc Visual::Base::SetSize
    */
   virtual void SetSize( const Vector2& size );
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
   /**
-   * @copydoc Visual::DoInitialize
+   * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
index 30eeeda..1ce668b 100644 (file)
@@ -227,6 +227,8 @@ void BatchImageVisual::DoSetOnStage( Actor& actor )
   }
   // Turn batching on, to send message it must be on stage
   mImpl->mRenderer.SetProperty( Dali::Renderer::Property::BATCHING_ENABLED, true );
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void BatchImageVisual::DoSetOffStage( Actor& actor )
index 0984326..540f7c2 100644 (file)
@@ -588,6 +588,8 @@ void ImageVisual::DoSetOnStage( Actor& actor )
   {
     mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea );
   }
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void ImageVisual::DoSetOffStage( Actor& actor )
index 64b3f4b..2c48913 100644 (file)
@@ -91,28 +91,28 @@ public:
 public:  // from Visual
 
   /**
-   * @copydoc Visual::GetNaturalSize
+   * @copydoc Visual::Base::GetNaturalSize
    */
   virtual void GetNaturalSize( Vector2& naturalSize ) const;
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
   /**
-   * @copydoc Visual::DoInitialize
+   * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
   /**
-   * @copydoc Visual::DoSetOffStage
+   * @copydoc Visual::Base::DoSetOffStage
    */
   virtual void DoSetOffStage( Actor& actor );
 
index b995e91..eafe9e8 100644 (file)
@@ -372,6 +372,8 @@ void MeshVisual::SetSize( const Vector2& size )
 void MeshVisual::DoSetOnStage( Actor& actor )
 {
   InitializeRenderer();
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void MeshVisual::DoCreatePropertyMap( Property::Map& map ) const
index 67e1fe1..4a2927c 100644 (file)
@@ -70,24 +70,24 @@ public:
 public:  // from Visual
 
   /**
-   * @copydoc Visual::SetSize
+   * @copydoc Visual::Base::SetSize
    */
   virtual void SetSize( const Vector2& size );
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
 
   /**
-   * @copydoc Visual::DoInitialize
+   * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
index 5dc9e04..3bf5728 100644 (file)
@@ -379,6 +379,8 @@ void NPatchVisual::DoSetOnStage( Actor& actor )
   {
     ApplyImageToSampler();
   }
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void NPatchVisual::DoSetOffStage( Actor& actor )
index 498bcc2..a993303 100644 (file)
@@ -68,29 +68,29 @@ public:
 public:  // from Visual
 
   /**
-   * @copydoc Visual::GetNaturalSize
+   * @copydoc Visual::Base::GetNaturalSize
    */
   virtual void GetNaturalSize( Vector2& naturalSize ) const;
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
 
   /**
-   * @copydoc Visual::DoInitialize
+   * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
   /**
-   * @copydoc Visual::DoSetOffStage
+   * @copydoc Visual::Base::DoSetOffStage
    */
   virtual void DoSetOffStage( Actor& actor );
 
index fa40339..6991f32 100644 (file)
@@ -383,6 +383,8 @@ void PrimitiveVisual::GetNaturalSize( Vector2& naturalSize ) const
 void PrimitiveVisual::DoSetOnStage( Actor& actor )
 {
   InitializeRenderer();
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void PrimitiveVisual::DoCreatePropertyMap( Property::Map& map ) const
index 45b536b..054e9f0 100644 (file)
@@ -111,29 +111,29 @@ public:
 public:  // from Visual
 
   /**
-   * @copydoc Visual::SetSize
+   * @copydoc Visual::Base::SetSize
    */
   virtual void SetSize( const Vector2& size );
 
   /**
-   * @copydoc Visual::GetNaturalSize
+   * @copydoc Visual::Base::GetNaturalSize
    */
   virtual void GetNaturalSize( Vector2& naturalSize ) const;
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
 
   /**
-   * @copydoc Visual::DoInitialize
+   * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
index 569c696..832fd19 100644 (file)
@@ -104,6 +104,9 @@ void SvgVisual::DoSetOnStage( Actor& actor )
   {
     AddRasterizationTask( mImpl->mSize );
   }
+
+  // Hold the weak handle of the placement actor and delay the adding of renderer until the svg rasterization is finished.
+  mPlacementActor = actor;
 }
 
 void SvgVisual::DoSetOffStage( Actor& actor )
@@ -112,6 +115,7 @@ void SvgVisual::DoSetOffStage( Actor& actor )
 
   actor.RemoveRenderer( mImpl->mRenderer );
   mImpl->mRenderer.Reset();
+  mPlacementActor.Reset();
 }
 
 void SvgVisual::GetNaturalSize( Vector2& naturalSize ) const
@@ -232,11 +236,19 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
         TextureSetImage( textureSet, 0u, texture );
       }
     }
+
+    // Rasterized pixels are uploaded to texture. If weak handle is holding a placement actor, it is the time to add the renderer to actor.
+    Actor actor = mPlacementActor.GetHandle();
+    if( actor )
+    {
+      actor.AddRenderer( mImpl->mRenderer );
+      // reset the weak handle so that the renderer only get added to actor once
+      mPlacementActor.Reset();
+    }
   }
 }
 
 
-
 } // namespace Internal
 
 } // namespace Toolkit
index c583035..81672e5 100644 (file)
@@ -18,6 +18,9 @@
  *
  */
 
+//EXTERNAL INCLUDES
+#include <dali/devel-api/object/weak-handle.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 
@@ -61,34 +64,34 @@ public:
 public:  // from Visual
 
   /**
-   * @copydoc Visual::GetNaturalSize
+   * @copydoc Visual::Base::GetNaturalSize
    */
   virtual void GetNaturalSize( Vector2& naturalSize ) const;
 
   /**
-   * @copydoc Visual::SetSize
+   * @copydoc Visual::Base::SetSize
    */
   virtual void SetSize( const Vector2& size );
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
 
   /**
-   * @copydoc Visual::DoInitialize
+   * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
   /**
-   * @copydoc Visual::DoSetOffStage
+   * @copydoc Visual::Base::DoSetOffStage
    */
   virtual void DoSetOffStage( Actor& actor );
 
@@ -129,6 +132,7 @@ private:
   Vector4              mAtlasRect;
   std::string          mImageUrl;
   NSVGimage*           mParsedImage;
+  WeakHandle<Actor>    mPlacementActor;
 
 };
 
index 58e4d38..8356de5 100644 (file)
@@ -105,12 +105,12 @@ float Visual::Base::GetDepthIndex() const
 
 void Visual::Base::SetOnStage( Actor& actor )
 {
+  // To display the actor correctly, renderer should not be added to actor until all required resources are ready.
+  // Thus the calling of actor.AddRenderer() should happen inside derived class as base class does not know the exact timing.
   DoSetOnStage( actor );
 
   mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled());
   mImpl->mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex );
-  actor.AddRenderer( mImpl->mRenderer );
-
   mImpl->mFlags |= Impl::IS_ON_STAGE;
 }
 
@@ -146,10 +146,6 @@ bool Visual::Base::IsPreMultipliedAlphaEnabled() const
   return mImpl->mFlags & Impl::IS_PREMULTIPLIED_ALPHA;
 }
 
-void Visual::Base::DoSetOnStage( Actor& actor )
-{
-}
-
 void Visual::Base::DoSetOffStage( Actor& actor )
 {
   actor.RemoveRenderer( mImpl->mRenderer );
index 8068dd8..3820bd0 100644 (file)
@@ -170,9 +170,11 @@ protected:
   /**
    * @brief Called by SetOnStage() allowing sub classes to respond to the SetOnStage event
    *
+   * @note The derived class is required to create the renderer, and add it to the actor when all the resources are in place.
+   *
    * @param[in] actor The actor applying this visual.
    */
-  virtual void DoSetOnStage( Actor& actor );
+  virtual void DoSetOnStage( Actor& actor )=0;
 
   /**
    * @brief Called by SetOffStage() allowing sub classes to respond to the SetOffStage event
index 47474a6..4299eb6 100644 (file)
@@ -76,6 +76,8 @@ WireframeVisual::~WireframeVisual()
 void WireframeVisual::DoSetOnStage( Actor& actor )
 {
   InitializeRenderer();
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void WireframeVisual::DoCreatePropertyMap( Property::Map& map ) const
index b14452a..c0d8682 100644 (file)
@@ -53,12 +53,12 @@ public:
 protected:
 
   /**
-   * @copydoc Visual::DoSetOnStage
+   * @copydoc Visual::Base::DoSetOnStage
    */
   virtual void DoSetOnStage( Actor& actor );
 
   /**
-   * @copydoc Visual::CreatePropertyMap
+   * @copydoc Visual::Base::CreatePropertyMap
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
index 23745bb..cc3546c 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/rendering/renderer.h>
 #include <dali/public-api/size-negotiation/relayout-container.h>
+#include <dali/devel-api/common/owner-container.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
 
@@ -63,14 +64,16 @@ struct RegisteredVisual
   RegisteredVisual( Property::Index aIndex, Toolkit::Visual::Base &aVisual, Actor &aPlacementActor) : index(aIndex), visual(aVisual), placementActor(aPlacementActor) {}
 };
 
+typedef Dali::OwnerContainer< RegisteredVisual* > RegisteredVisuals;
+
 /**
  *  Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
  */
-bool FindVisual( Property::Index targetIndex, std::vector<RegisteredVisual>& visuals, std::vector<RegisteredVisual>::iterator& iter )
+bool FindVisual( Property::Index targetIndex, RegisteredVisuals& visuals, RegisteredVisuals::Iterator& iter )
 {
-  for ( iter = visuals.begin(); iter != visuals.end(); iter++ )
+  for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
   {
-    if ( (*iter).index ==  targetIndex )
+    if ( (*iter)->index ==  targetIndex )
     {
       return true;
     }
@@ -394,7 +397,7 @@ public:
   // Data
 
   Control& mControlImpl;
-  std::vector<RegisteredVisual> mVisuals; // Stores visuals needed by the control, non trivial type so std::vector used.
+  RegisteredVisuals mVisuals; // Stores visuals needed by the control, non trivial type so std::vector used.
   std::string mStyleName;
   Toolkit::Visual::Base mBackgroundVisual;   ///< The visual to render the background
   Vector4 mBackgroundColor;                       ///< The color of the background visual
@@ -475,7 +478,8 @@ void Control::SetBackgroundColor( const Vector4& color )
   Property::Map map;
   map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
   map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
-  InitializeVisual( self, mImpl->mBackgroundVisual, map );
+  mImpl->mBackgroundVisual = Toolkit::VisualFactory::Get().CreateVisual( map );
+  RegisterVisual( Toolkit::Control::Property::BACKGROUND, self, mImpl->mBackgroundVisual );
   if( mImpl->mBackgroundVisual )
   {
     mImpl->mBackgroundVisual.SetDepthIndex( DepthIndex::BACKGROUND );
@@ -490,7 +494,8 @@ Vector4 Control::GetBackgroundColor() const
 void Control::SetBackground( const Property::Map& map )
 {
   Actor self( Self() );
-  InitializeVisual( self, mImpl->mBackgroundVisual, map );
+  mImpl->mBackgroundVisual = Toolkit::VisualFactory::Get().CreateVisual( map );
+  RegisterVisual( Toolkit::Control::Property::BACKGROUND, self, mImpl->mBackgroundVisual );
   if( mImpl->mBackgroundVisual )
   {
     mImpl->mBackgroundVisual.SetDepthIndex( DepthIndex::BACKGROUND );
@@ -500,7 +505,8 @@ void Control::SetBackground( const Property::Map& map )
 void Control::SetBackgroundImage( Image image )
 {
   Actor self( Self() );
-  InitializeVisual( self, mImpl->mBackgroundVisual, image );
+  mImpl->mBackgroundVisual = Toolkit::VisualFactory::Get().CreateVisual( image );
+  RegisterVisual( Toolkit::Control::Property::BACKGROUND, self, mImpl->mBackgroundVisual );
   if( mImpl->mBackgroundVisual )
   {
     mImpl->mBackgroundVisual.SetDepthIndex( DepthIndex::BACKGROUND );
@@ -653,63 +659,79 @@ void Control::KeyboardEnter()
   OnKeyboardEnter();
 }
 
-void Control::RegisterVisual( Property::Index index, Actor placementActor, Toolkit::Visual::Base visual )
+void Control::RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual )
 {
   bool visualReplaced ( false );
   Actor actorToRegister; // Null actor, replaced if placement actor not Self
+  Actor self = Self();
 
-  if ( placementActor != Self() ) // Prevent increasing ref count if actor self
+  if ( placementActor != self ) // Prevent increasing ref count if actor self
   {
     actorToRegister = placementActor;
   }
 
-  if ( !mImpl->mVisuals.empty() )
+  if ( !mImpl->mVisuals.Empty() )
   {
-      std::vector<RegisteredVisual>::iterator iter;
+      RegisteredVisuals::Iterator iter;
       // Check if visual (index) is already registered.  Replace if so.
       if ( FindVisual( index, mImpl->mVisuals, iter ) )
       {
-        (*iter).visual = visual;
-        (*iter).placementActor = actorToRegister;
+        if( (*iter)->visual && self.OnStage() )
+        {
+          if( (*iter)->placementActor )
+          {
+            (*iter)->visual.SetOffStage( (*iter)->placementActor );
+          }
+          else
+          {
+            (*iter)->visual.SetOffStage( self );
+          }
+        }
+        (*iter)->visual = visual;
+        (*iter)->placementActor = actorToRegister;
         visualReplaced = true;
       }
   }
 
   if ( !visualReplaced ) // New registration entry
   {
-    RegisteredVisual newVisual = RegisteredVisual( index, visual, actorToRegister );
-    mImpl->mVisuals.push_back( newVisual );
+    mImpl->mVisuals.PushBack( new RegisteredVisual( index, visual, actorToRegister ) );
+  }
+
+  if( visual && self.OnStage() )
+  {
+    visual.SetOnStage( placementActor );
   }
 }
 
 void Control::UnregisterVisual( Property::Index index )
 {
-   std::vector< RegisteredVisual >::iterator iter;
+   RegisteredVisuals::Iterator iter;
    if ( FindVisual( index, mImpl->mVisuals, iter ) )
    {
-     mImpl->mVisuals.erase( iter );
+     mImpl->mVisuals.Erase( iter );
    }
 }
 
-Toolkit::Visual::Base Control::GetVisual( Property::Index index )
+Toolkit::Visual::Base Control::GetVisual( Property::Index index ) const
 {
-  std::vector< RegisteredVisual >::iterator iter;
+  RegisteredVisuals::Iterator iter;
   if ( FindVisual( index, mImpl->mVisuals, iter ) )
   {
-    return (*iter).visual;
+    return (*iter)->visual;
   }
 
   return Toolkit::Visual::Base();
 }
 
-Actor Control::GetPlacementActor( Property::Index index )
+Actor Control::GetPlacementActor( Property::Index index ) const
 {
-  std::vector< RegisteredVisual >::iterator iter;
+  RegisteredVisuals::Iterator iter;
   if ( FindVisual( index, mImpl->mVisuals, iter ) )
   {
-    if( (*iter).placementActor )
+    if( (*iter)->placementActor )
     {
-      return (*iter).placementActor;
+      return (*iter)->placementActor;
     }
     else
     {
@@ -905,19 +927,41 @@ void Control::EmitKeyInputFocusSignal( bool focusGained )
 
 void Control::OnStageConnection( int depth )
 {
-  if( mImpl->mBackgroundVisual)
+  for(RegisteredVisuals::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
   {
-    Actor self( Self() );
-    mImpl->mBackgroundVisual.SetOnStage( self );
+    // Check whether the visual is empty, as it is allowed to register a placement actor without visual.
+    if( (*iter)->visual )
+    {
+      if( (*iter)->placementActor )
+      {
+        (*iter)->visual.SetOnStage( (*iter)->placementActor );
+      }
+      else
+      {
+        Actor self( Self() );
+        (*iter)->visual.SetOnStage( self );
+      }
+    }
   }
 }
 
 void Control::OnStageDisconnection()
 {
-  if( mImpl->mBackgroundVisual )
+  for(RegisteredVisuals::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
   {
-    Actor self( Self() );
-    mImpl->mBackgroundVisual.SetOffStage( self );
+    // Check whether the visual is empty, as it is allowed to register a placement actor without visual.
+    if( (*iter)->visual )
+    {
+      if( (*iter)->placementActor )
+      {
+        (*iter)->visual.SetOffStage( (*iter)->placementActor );
+      }
+      else
+      {
+        Actor self( Self() );
+        (*iter)->visual.SetOffStage( self );
+      }
+    }
   }
 }
 
index e8a71fe..97ed7d1 100644 (file)
@@ -305,8 +305,9 @@ protected: // For derived classes to call
    * @param[in] index The Property index of the visual, used to reference visual
    * @param[in] placementActor The actor used to by the visual.
    * @param[in] visual The visual to register
+   * @note Derived class must NOT call visual.SetOnStage(placementActor). It is the responsibility of the base class to connect/disconnect registered visual to stage.
    */
-   void RegisterVisual( Property::Index index, Actor placementActor, Toolkit::Visual::Base visual );
+   void RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual );
 
    /**
     * @brief Erase the entry matching the given index from the list of registered visuals
@@ -325,7 +326,7 @@ protected: // For derived classes to call
     * @return The registered visual if exist, otherwise empty handle.
     * @note For managing object life-cycle, do not store the returned visual as a member which increments its reference count.
     */
-   Toolkit::Visual::Base GetVisual( Property::Index index );
+   Toolkit::Visual::Base GetVisual( Property::Index index ) const;
 
    /**
     * @brief Retrieve the placement actor associated with the given index.
@@ -336,7 +337,7 @@ protected: // For derived classes to call
     * @return Then placement actor if exist, otherwise empty handle.
     * @note For managing object life-cycle, do not store the returned placement actor as a member which increments its reference count.
     */
-   Actor GetPlacementActor( Property::Index index );
+   Actor GetPlacementActor( Property::Index index ) const;
 
   /**
    * @brief Emits KeyInputFocusGained signal if true else emits KeyInputFocusLost signal