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();
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
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.
*
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
*
visual = visualFactory.CreateVisual( map );
RegisterVisual( visualIndex, placementActor, visual );
- visual.SetOnStage( placementActor );
SetupContent( *contentActor, placementActor ); //
contentActor->SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
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();
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 )
}
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 );
// 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 );
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 );
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
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;
void ColorVisual::DoSetOnStage( Actor& actor )
{
InitializeRenderer();
+
+ actor.AddRenderer( mImpl->mRenderer );
}
void ColorVisual::DoCreatePropertyMap( Property::Map& map ) const
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 );
void GradientVisual::DoSetOnStage( Actor& actor )
{
InitializeRenderer();
+
+ actor.AddRenderer( mImpl->mRenderer );
}
void GradientVisual::DoCreatePropertyMap( Property::Map& map ) const
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 );
}
// 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 )
{
mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea );
}
+
+ actor.AddRenderer( mImpl->mRenderer );
}
void ImageVisual::DoSetOffStage( Actor& actor )
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 );
void MeshVisual::DoSetOnStage( Actor& actor )
{
InitializeRenderer();
+
+ actor.AddRenderer( mImpl->mRenderer );
}
void MeshVisual::DoCreatePropertyMap( Property::Map& map ) const
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 );
{
ApplyImageToSampler();
}
+
+ actor.AddRenderer( mImpl->mRenderer );
}
void NPatchVisual::DoSetOffStage( Actor& actor )
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 );
void PrimitiveVisual::DoSetOnStage( Actor& actor )
{
InitializeRenderer();
+
+ actor.AddRenderer( mImpl->mRenderer );
}
void PrimitiveVisual::DoCreatePropertyMap( Property::Map& map ) const
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 );
{
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 )
actor.RemoveRenderer( mImpl->mRenderer );
mImpl->mRenderer.Reset();
+ mPlacementActor.Reset();
}
void SvgVisual::GetNaturalSize( Vector2& naturalSize ) const
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
*
*/
+//EXTERNAL INCLUDES
+#include <dali/devel-api/object/weak-handle.h>
+
// INTERNAL INCLUDES
#include <dali-toolkit/internal/visuals/visual-base-impl.h>
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 );
Vector4 mAtlasRect;
std::string mImageUrl;
NSVGimage* mParsedImage;
+ WeakHandle<Actor> mPlacementActor;
};
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;
}
return mImpl->mFlags & Impl::IS_PREMULTIPLIED_ALPHA;
}
-void Visual::Base::DoSetOnStage( Actor& actor )
-{
-}
-
void Visual::Base::DoSetOffStage( Actor& actor )
{
actor.RemoveRenderer( mImpl->mRenderer );
/**
* @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
void WireframeVisual::DoSetOnStage( Actor& actor )
{
InitializeRenderer();
+
+ actor.AddRenderer( mImpl->mRenderer );
}
void WireframeVisual::DoCreatePropertyMap( Property::Map& map ) const
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;
#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>
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;
}
// 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
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 );
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 );
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 );
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
{
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 );
+ }
+ }
}
}
* @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
* @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.
* @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