in the hierarchy.
Change-Id: I68965e1df12840953e416221f1c539d0fa4004c1
mDaliProperty( Property::INVALID_INDEX ),
mSizeSet( Vector3::ZERO ),
mTargetSize( Vector3::ZERO ),
- mNego( false )
+ mNego( false ),
+ mDepth(0u)
{
}
}
// From CustomActorImpl
- virtual void OnStageConnection()
+ virtual void OnStageConnection( unsigned int depth )
{
AddToCallStacks("OnStageConnection");
+ mDepth = depth;
}
virtual void OnStageDisconnection()
{
Vector3 mSizeSet;
Vector3 mTargetSize;
bool mNego;
+ unsigned int mDepth;
};
/**
}
// From CustomActorImpl
- virtual void OnStageConnection()
+ virtual void OnStageConnection( unsigned int depth )
{
// Chain up first
- TestCustomActor::OnStageConnection();
+ TestCustomActor::OnStageConnection( depth );
// Add the child
Self().Add( mChildToAdd );
}
// From CustomActorImpl
- virtual void OnStageConnection()
+ virtual void OnStageConnection( unsigned int depth )
{
// Chain up first
- TestCustomActor::OnStageConnection();
+ TestCustomActor::OnStageConnection( depth );
// Remove all the children
for( unsigned int i=0, num=Self().GetChildCount(); i<num; ++i )
}
// From CustomActorImpl
- virtual void OnStageConnection()
+ virtual void OnStageConnection( unsigned int depth )
{
// Chain up first
- TestCustomActor::OnStageConnection();
+ TestCustomActor::OnStageConnection( depth );
// Take parent off-stage
Actor parent = Self().GetParent();
}
// From CustomActorImpl
- virtual void OnStageConnection()
+ virtual void OnStageConnection( unsigned int depth )
{
}
virtual void OnStageDisconnection()
return GetImpl().TestRelayoutDependentOnChildrenBase( dimension );
}
+ unsigned int GetDepth()
+ {
+ return GetImpl().mDepth;
+ }
private:
TestCustomActor( Impl::TestCustomActor& impl ) : CustomActor( impl )
END_TEST;
}
+
+int UtcDaliCustomActorOnConnectionDepth(void)
+{
+ TestApplication application;
+ tet_infoline("Testing Dali::CustomActor::OnStageConnection() hierarchy depth");
+
+ Stage stage = Stage::GetCurrent();
+
+ /* Build tree of actors:
+ *
+ * Depth
+ *
+ * A (parent) 1
+ * / \
+ * B C 2
+ * / \ \
+ * D E F 3
+ *
+ * OnStageConnection should return 1 for A, 2 for B and C, and 3 for D, E and F.
+ */
+
+ TestCustomActor actorA = TestCustomActor::New();
+ stage.Add( actorA );
+
+ TestCustomActor actorB = TestCustomActor::New();
+ actorA.Add( actorB );
+
+ TestCustomActor actorC = TestCustomActor::New();
+ actorA.Add( actorC );
+
+ TestCustomActor actorD = TestCustomActor::New();
+ actorB.Add( actorD );
+
+ TestCustomActor actorE = TestCustomActor::New();
+ actorB.Add( actorE );
+
+ TestCustomActor actorF = TestCustomActor::New();
+ actorC.Add( actorF );
+
+ // Excercise the message passing to Update thread
+ application.SendNotification();
+ application.Render();
+ application.Render();
+
+ DALI_TEST_EQUALS( 1u, actorA.GetDepth(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 2u, actorB.GetDepth(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 2u, actorC.GetDepth(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 3u, actorD.GetDepth(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 3u, actorE.GetDepth(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 3u, actorF.GetDepth(), TEST_LOCATION );
+
+ END_TEST;
+}
}
// From CustomActorImpl
- virtual void OnStageConnection()
+ virtual void OnStageConnection( unsigned int depth )
{
}
virtual void OnStageDisconnection()
}
}
-void Actor::ConnectToStage( int index )
+void Actor::ConnectToStage( unsigned int parentDepth, int index )
{
// This container is used instead of walking the Actor hierachy.
// It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
ActorContainer connectionList;
+
// This stage is atomic i.e. not interrupted by user callbacks
- RecursiveConnectToStage( connectionList, index );
+ RecursiveConnectToStage( connectionList, parentDepth+1, index );
// Notify applications about the newly connected actors.
const ActorIter endIter = connectionList.end();
RelayoutRequest();
}
-void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
+void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth, int index )
{
DALI_ASSERT_ALWAYS( !OnStage() );
mIsOnStage = true;
+ mDepth = depth;
ConnectToSceneGraph( index );
for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
{
Actor& actor = GetImplementation( *iter );
- actor.RecursiveConnectToStage( connectionList );
+ actor.RecursiveConnectToStage( connectionList, depth+1 );
}
}
}
if( OnStage() && !mOnStageSignalled )
{
// Notification for external (CustomActor) derived classes
- OnStageConnectionExternal();
+ OnStageConnectionExternal( mDepth );
if( !mOnStageSignal.Empty() )
{
parent->OnStage() )
{
// Instruct each actor to create a corresponding node in the scene graph
- ConnectToStage( index );
+ ConnectToStage( parent->GetDepth(), index );
}
}
else // parent being set to NULL
/**
* Called on a child during Add() when the parent actor is connected to the Stage.
* @param[in] stage The stage.
+ * @param[in] parentDepth The depth of the parent in the hierarchy
* @param[in] index If set, it is only used for positioning the actor within the parent's child list.
*/
- void ConnectToStage( int index = -1 );
+ void ConnectToStage( unsigned int parentDepth, int index = -1 );
/**
* Helper for ConnectToStage, to recursively connect a tree of actors.
* This is atomic i.e. not interrupted by user callbacks.
* @param[in] index If set, it is only used for positioning the actor within the parent's child list.
+ * @param[in] depth The depth in the hierarchy of the actor
* @param[out] connectionList On return, the list of connected actors which require notification.
*/
- void RecursiveConnectToStage( ActorContainer& connectionList, int index = -1 );
+ void RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth, int index = -1 );
/**
* Connect the Node associated with this Actor to the scene-graph.
*/
float CalculateSizeZ( const Vector2& size ) const;
+ /**
+ * Return the depth in the hierarchy of the actor.
+ * The value returned is only valid if the actor is on the stage.
+ *
+ * @return Depth of the actor in the hierarchy
+ */
+ unsigned int GetDepth() const
+ {
+ return mDepth;
+ }
+
public:
// Default property extensions from Object
* For use in external (CustomActor) derived classes.
* This is called after the atomic ConnectToStage() traversal has been completed.
*/
- virtual void OnStageConnectionExternal()
+ virtual void OnStageConnectionExternal( unsigned int depth )
{
}
std::string mName; ///< Name of the actor
unsigned int mId; ///< A unique ID to identify the actor starting from 1, and 0 is reserved
+ unsigned int mDepth :12; ///< The depth in the hierarchy of the actor. Only 4096 levels of depth are supported
const bool mIsRoot : 1; ///< Flag to identify the root actor
const bool mIsRenderable : 1; ///< Flag to identify that this is a renderable actor
const bool mIsLayer : 1; ///< Flag to identify that this is a layer
/**
* @copydoc Internal::Actor::OnStageConnectionExternal
*/
- virtual void OnStageConnectionExternal()
+ virtual void OnStageConnectionExternal( unsigned int depth )
{
- mImpl->OnStageConnection();
+ mImpl->OnStageConnection( depth );
}
/**
* B C
* / \ \
* D E F
+ *
+ * @param[in] depth The depth in the hierarchy for the actor
*/
- virtual void OnStageConnection() = 0;
+ virtual void OnStageConnection( unsigned int depth ) = 0;
/**
* @brief Called after the actor has been disconnected from the stage.