#include <dali/public-api/math/radian.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/object/weak-handle.h>
#include <dali/devel-api/scripting/scripting.h>
#include <dali/internal/common/internal-constants.h>
#include <dali/internal/event/common/event-thread-services.h>
using Dali::Internal::SceneGraph::AnimatableProperty;
using Dali::Internal::SceneGraph::PropertyBase;
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
+Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
+#endif
+
namespace Dali
{
for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
{
resizePolicies[ i ] = ResizePolicy::DEFAULT;
+ useAssignedSize[ i ] = false;
negotiatedDimensions[ i ] = 0.0f;
dimensionNegotiated[ i ] = false;
dimensionDirty[ i ] = false;
}
ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies
+ bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor
Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies
return GetDimensionValue( values.GetVectorXY(), dimension );
}
-unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder )
+/**
+ * @brief Recursively emits the visibility-changed-signal on the actor tree.
+ * @param[in] actor The actor to emit the signal on
+ * @param[in] visible The new visibility of the actor
+ * @param[in] type Whether the actor's visible property has changed or a parent's
+ */
+void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
{
- return depth * Dali::DevelLayer::ACTOR_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
+ if( actor )
+ {
+ actor->EmitVisibilityChangedSignal( visible, type );
+
+ if( actor->GetChildCount() > 0 )
+ {
+ ActorContainer& children = actor->GetChildrenInternal();
+ for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
+ {
+ EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT );
+ }
+ }
+ }
}
} // unnamed namespace
Vector3 actorSize = GetCurrentSize() * GetCurrentScale();
Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
Vector3 halfActorSize( actorSize * 0.5f );
- // Anchor point offset first set to TOP_LEFT (0,0.5) then moved to required anchor point.
- Vector3 anchorPointOffSet = halfActorSize - actorSize * GetCurrentAnchorPoint();
+ Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x,
halfStageSize.height + worldPosition.y - anchorPointOffSet.y );
void Actor::SetOrientation( const Quaternion& orientation )
{
+ mTargetOrientation = orientation;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::RotateBy( const Radian& angle, const Vector3& axis )
{
- if( NULL != mNode )
- {
- // mNode is being used in a separate thread; queue a message to set the value & base value
- SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, Quaternion(angle, axis) );
- }
+ RotateBy( Quaternion(angle, axis) );
}
void Actor::RotateBy( const Quaternion& relativeRotation )
{
+ mTargetOrientation *= Quaternion( relativeRotation );
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::SetScale( const Vector3& scale )
{
+ mTargetScale = scale;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::SetScaleX( float x )
{
+ mTargetScale.x = x;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::SetScaleY( float y )
{
+ mTargetScale.y = y;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::SetScaleZ( float z )
{
+ mTargetScale.z = z;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::ScaleBy(const Vector3& relativeScale)
{
+ mTargetScale *= relativeScale;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::SetVisible( bool visible )
{
- if( NULL != mNode )
+ if( mVisible != visible )
{
- // mNode is being used in a separate thread; queue a message to set the value & base value
- SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
+ if( NULL != mNode )
+ {
+ // mNode is being used in a separate thread; queue a message to set the value & base value
+ SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
+ }
+
+ mVisible = visible;
+
+ // Emit the signal on this actor and all its children
+ EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
}
}
void Actor::SetOpacity( float opacity )
{
+ mTargetColor.a = opacity;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
unsigned int Actor::GetSortingDepth()
{
- return GetDepthIndex( mDepth, mSiblingOrder );
+ return mSortedDepth;
}
const Vector4& Actor::GetCurrentWorldColor() const
void Actor::SetColor( const Vector4& color )
{
+ mTargetColor = color;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::SetColorRed( float red )
{
+ mTargetColor.r = red;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::SetColorGreen( float green )
{
+ mTargetColor.g = green;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
void Actor::SetColorBlue( float blue )
{
+ mTargetColor.b = blue;
+
if( NULL != mNode )
{
// mNode is being used in a separate thread; queue a message to set the value & base value
}
}
-const Vector3& Actor::GetTargetSize() const
+Vector3 Actor::GetTargetSize() const
{
- return mTargetSize;
+ Vector3 size = mTargetSize;
+
+ // Should return preferred size if size is fixed as set by SetSize
+ if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
+ {
+ size.width = GetPreferredSize().width;
+ }
+ if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
+ {
+ size.height = GetPreferredSize().height;
+ }
+
+ return size;
}
const Vector3& Actor::GetCurrentSize() const
{
if( dimension & ( 1 << i ) )
{
- mRelayoutData->resizePolicies[ i ] = policy;
+ if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
+ {
+ mRelayoutData->useAssignedSize[ i ] = true;
+ }
+ else
+ {
+ mRelayoutData->resizePolicies[ i ] = policy;
+ mRelayoutData->useAssignedSize[ i ] = false;
+ }
}
}
{
if( ( dimension & ( 1 << i ) ) )
{
- return mRelayoutData->resizePolicies[ i ];
+ if( mRelayoutData->useAssignedSize[ i ] )
+ {
+ return ResizePolicy::USE_ASSIGNED_SIZE;
+ }
+ else
+ {
+ return mRelayoutData->resizePolicies[ i ];
+ }
}
}
}
return consumed;
}
+void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
+{
+ if( ! mVisibilityChangedSignal.Empty() )
+ {
+ Dali::Actor handle( this );
+ mVisibilityChangedSignal.Emit( handle, visible, type );
+ }
+}
+
Dali::Actor::TouchSignalType& Actor::TouchedSignal()
{
return mTouchedSignal;
return mOnRelayoutSignal;
}
+DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
+{
+ return mVisibilityChangedSignal;
+}
+
bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
{
bool connected( true );
mAnchorPoint( NULL ),
mRelayoutData( NULL ),
mGestureData( NULL ),
- mTargetSize( 0.0f, 0.0f, 0.0f ),
+ mTargetOrientation( Quaternion::IDENTITY ),
+ mTargetColor( Color::WHITE ),
+ mTargetSize( Vector3::ZERO ),
+ mTargetPosition( Vector3::ZERO ),
+ mTargetScale( Vector3::ONE ),
mName(),
mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
+ mSortedDepth( 0u ),
mDepth( 0u ),
mSiblingOrder(0u),
mIsRoot( ROOT_LAYER == derivedType ),
mInheritOrientation( true ),
mInheritScale( true ),
mPositionUsesAnchorPoint( true ),
+ mVisible( true ),
mDrawMode( DrawMode::NORMAL ),
mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
mColorMode( Node::DEFAULT_COLOR_MODE ),
// It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
ActorContainer connectionList;
+ StagePtr stage = Stage::GetCurrent();
+ if( stage )
+ {
+ stage->RequestRebuildDepthTree();
+ }
+
// This stage is atomic i.e. not interrupted by user callbacks.
RecursiveConnectToStage( connectionList, parentDepth + 1 );
mIsOnStage = true;
mDepth = depth;
- SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
ConnectToSceneGraph();
// It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
ActorContainer disconnectionList;
+ StagePtr stage = Stage::GetCurrent();
+ if( stage )
+ {
+ stage->RequestRebuildDepthTree();
+ }
+
// This stage is atomic i.e. not interrupted by user callbacks
RecursiveDisconnectFromStage( disconnectionList );
return connected;
}
+// This method generates the depth tree using the recursive function below,
+// then walks the tree and sets a depth index based on traversal order. It
+// sends a single message to update manager to update all the actor's nodes in this
+// tree with the depth index. The sceneGraphNodeDepths vector's elements are ordered
+// by depth, and could be used to reduce sorting in the update thread.
+void Actor::RebuildDepthTree()
+{
+ DALI_LOG_TIMER_START(depthTimer);
+
+ DepthNodeMemoryPool nodeMemoryPool;
+ ActorDepthTreeNode* rootNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( this, mSiblingOrder );
+
+ int actorCount = BuildDepthTree( nodeMemoryPool, rootNode );
+
+ // Vector of scene-graph nodes and their depths to send to UpdateManager
+ // in a single message
+ SceneGraph::NodeDepths* sceneGraphNodeDepths = new SceneGraph::NodeDepths(actorCount);
+
+ // Traverse depth tree and set mSortedDepth on each actor and scenegraph node
+ uint32_t sortOrder = 1u; // Don't start at zero, as visual depth can be negative
+ ActorDepthTreeNode* currentNode = rootNode;
+ bool firstVisit = true;
+ while( currentNode != rootNode || firstVisit)
+ {
+ firstVisit = false;
+
+ // Visit node, performing action
+ for( std::vector<Actor*>::iterator iter = currentNode->mActors.begin(); iter != currentNode->mActors.end(); ++iter )
+ {
+ (*iter)->mSortedDepth = sortOrder * DevelLayer::SIBLING_ORDER_MULTIPLIER;
+ sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>((*iter)->mNode), (*iter)->mSortedDepth );
+ }
+ ++sortOrder;
+
+ // Descend tree
+ if( currentNode->mFirstChildNode )
+ {
+ currentNode = currentNode->mFirstChildNode;
+ }
+ else // leaf node, goto next sibling, or return up tree.
+ {
+ bool breakout=false;
+ while( ! currentNode->mNextSiblingNode )
+ {
+ if( currentNode == rootNode ) // If we get to root of tree, stop
+ {
+ breakout = true;
+ break;
+ }
+ currentNode = currentNode->mParentNode;
+ }
+
+ if( breakout )
+ {
+ break;
+ }
+ currentNode = currentNode->mNextSiblingNode;
+ }
+ }
+
+ SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
+ DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree create time: ");
+}
+
+/**
+ * Structure to store the actor's associated node in the depth tree for child
+ * traversal
+ */
+struct ActorNodePair
+{
+ Actor* actor;
+ ActorDepthTreeNode* node;
+ ActorNodePair( Actor* actor, ActorDepthTreeNode* node )
+ : actor(actor),
+ node(node)
+ {
+ }
+};
+
+/*
+ * Descend actor tree, building a depth tree based on actor's sibling order.
+ * Actors with the same sibling order share the same depth tree. Siblings
+ * in the depth tree are ordered by actor's sibling order.
+ *
+ * An actor tree like this:
+ *
+ * Root (SO:0)
+ * _/ | \_
+ * _/ | \_
+ * _/ | \_
+ * / | \
+ * A(SO:1) B(SO:2) C(SO:1)
+ * _/\_ | _/ \_
+ * / \ | / \
+ * D(SO:0) E(SO:0) F(SO:0) G(SO:1) H(SO:0)
+ *
+ * will end up as a depth tree like this:
+ *
+ * RootNode [ Root ] -> NULL
+ * |(mFC)
+ * V (mNS)
+ * Node [ A, C ] ------------------------> Node [ B ] -> NULL
+ * | |
+ * V V
+ * Node [ D, E, H ] -> Node [ G ] -> NULL Node [ F ] -> NULL
+ * | | |
+ * V V V
+ * NULL NULL NULL
+ *
+ * (All nodes also point to their parents to enable storage free traversal)
+ */
+int Actor::BuildDepthTree( DepthNodeMemoryPool& nodeMemoryPool, ActorDepthTreeNode* node )
+{
+ int treeCount=1; // Count self and children
+
+ // Create/add to children of this node
+ if( mChildren )
+ {
+ std::vector<ActorNodePair> storedChildren;
+ storedChildren.reserve( mChildren->size() );
+
+ for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
+ {
+ Actor* childActor = (*it).Get();
+ if( childActor->IsLayer() )
+ {
+ Layer* layer = static_cast<Layer*>(childActor);
+ if( layer->GetBehavior() == Dali::Layer::LAYER_3D )
+ {
+ // Ignore this actor and children.
+ continue;
+ }
+ }
+
+ // If no existing depth node children
+ if( node->mFirstChildNode == NULL )
+ {
+ node->mFirstChildNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( childActor, childActor->mSiblingOrder );
+ node->mFirstChildNode->mParentNode = node;
+ storedChildren.push_back(ActorNodePair( childActor, node->mFirstChildNode ));
+ }
+ else // find child node with matching sibling order (insertion sort)
+ {
+ bool addedChildActor = false;
+
+ // depth tree child nodes ordered by sibling order
+ ActorDepthTreeNode* lastNode = NULL;
+ for( ActorDepthTreeNode* childNode = node->mFirstChildNode; childNode != NULL; childNode = childNode->mNextSiblingNode )
+ {
+ uint16_t actorSiblingOrder = childActor->mSiblingOrder;
+ uint16_t currentSiblingOrder = childNode->GetSiblingOrder();
+
+ if( actorSiblingOrder == currentSiblingOrder )
+ {
+ // Don't need a new depth node, add to existing node
+ childNode->AddActor( childActor );
+ storedChildren.push_back(ActorNodePair( childActor, childNode ));
+ addedChildActor = true;
+ break;
+ }
+ else if( actorSiblingOrder < currentSiblingOrder )
+ {
+ break;
+ }
+ lastNode = childNode;
+ }
+
+ // No matching sibling order - create new node and insert into sibling list
+ if( !addedChildActor )
+ {
+ ActorDepthTreeNode* newNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( childActor, childActor->mSiblingOrder );
+
+ newNode->mParentNode = node;
+ storedChildren.push_back(ActorNodePair( childActor, newNode ));
+
+ if( lastNode == NULL ) // Insert at start of siblings
+ {
+ ActorDepthTreeNode* nextNode = node->mFirstChildNode;
+ node->mFirstChildNode = newNode;
+ newNode->mNextSiblingNode = nextNode;
+ }
+ else // insert into siblings after last node
+ {
+ newNode->mNextSiblingNode = lastNode->mNextSiblingNode;
+ lastNode->mNextSiblingNode = newNode;
+ }
+ }
+ }
+ }
+
+ // Order of descent doesn't matter; we're using insertion to sort.
+ for( std::vector<ActorNodePair>::iterator iter = storedChildren.begin(); iter != storedChildren.end(); ++iter )
+ {
+ treeCount += iter->actor->BuildDepthTree( nodeMemoryPool, iter->node );
+ }
+ }
+ return treeCount;
+}
+
unsigned int Actor::GetDefaultPropertyCount() const
{
return DEFAULT_PROPERTY_COUNT;
{
Property::Value value;
- if( index >= DEFAULT_PROPERTY_COUNT )
+ if( ! GetCachedPropertyValue( index, value ) )
{
- return value;
+ // If property value is not stored in the event-side, then it must be a scene-graph only property
+ GetCurrentPropertyValue( index, value );
}
- switch( index )
+ return value;
+}
+
+Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
+{
+ Property::Value value;
+
+ if( ! GetCurrentPropertyValue( index, value ) )
{
- case Dali::Actor::Property::PARENT_ORIGIN:
- {
- value = GetCurrentParentOrigin();
- break;
- }
+ // If unable to retrieve scene-graph property value, then it must be an event-side only property
+ GetCachedPropertyValue( index, value );
+ }
- case Dali::Actor::Property::PARENT_ORIGIN_X:
- {
- value = GetCurrentParentOrigin().x;
- break;
- }
+ return value;
+}
- case Dali::Actor::Property::PARENT_ORIGIN_Y:
- {
- value = GetCurrentParentOrigin().y;
- break;
- }
+const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
+{
+ return mNode;
+}
- case Dali::Actor::Property::PARENT_ORIGIN_Z:
- {
- value = GetCurrentParentOrigin().z;
- break;
- }
+const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
+{
+ // This method should only return an object connected to the scene-graph
+ return OnStage() ? mNode : NULL;
+}
- case Dali::Actor::Property::ANCHOR_POINT:
- {
- value = GetCurrentAnchorPoint();
- break;
- }
+const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
+{
+ DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
- case Dali::Actor::Property::ANCHOR_POINT_X:
- {
- value = GetCurrentAnchorPoint().x;
- break;
- }
+ const PropertyBase* property( NULL );
- case Dali::Actor::Property::ANCHOR_POINT_Y:
- {
- value = GetCurrentAnchorPoint().y;
- break;
- }
+ // This method should only return a property of an object connected to the scene-graph
+ if( !OnStage() )
+ {
+ return property;
+ }
- case Dali::Actor::Property::ANCHOR_POINT_Z:
- {
- value = GetCurrentAnchorPoint().z;
- break;
- }
+ if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
+ {
+ AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
+ DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
- case Dali::Actor::Property::SIZE:
+ property = animatable->GetSceneGraphProperty();
+ }
+ else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
+ ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
+ {
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
+
+ property = custom->GetSceneGraphProperty();
+ }
+ else if( NULL != mNode )
+ {
+ switch( index )
{
- Vector3 size = GetTargetSize();
+ case Dali::Actor::Property::SIZE:
+ property = &mNode->mSize;
+ break;
- // Should return preferred size if size is fixed as set by SetSize
- if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
- {
- size.width = GetPreferredSize().width;
- }
- if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
- {
- size.height = GetPreferredSize().height;
- }
+ case Dali::Actor::Property::SIZE_WIDTH:
+ property = &mNode->mSize;
+ break;
- value = size;
+ case Dali::Actor::Property::SIZE_HEIGHT:
+ property = &mNode->mSize;
+ break;
- break;
- }
+ case Dali::Actor::Property::SIZE_DEPTH:
+ property = &mNode->mSize;
+ break;
- case Dali::Actor::Property::SIZE_WIDTH:
- {
- if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
- {
- // Should return preferred size if size is fixed as set by SetSize
- value = GetPreferredSize().width;
- }
- else
- {
- value = GetTargetSize().width;
- }
- break;
+ case Dali::Actor::Property::POSITION:
+ property = &mNode->mPosition;
+ break;
+
+ case Dali::Actor::Property::POSITION_X:
+ property = &mNode->mPosition;
+ break;
+
+ case Dali::Actor::Property::POSITION_Y:
+ property = &mNode->mPosition;
+ break;
+
+ case Dali::Actor::Property::POSITION_Z:
+ property = &mNode->mPosition;
+ break;
+
+ case Dali::Actor::Property::ORIENTATION:
+ property = &mNode->mOrientation;
+ break;
+
+ case Dali::Actor::Property::SCALE:
+ property = &mNode->mScale;
+ break;
+
+ case Dali::Actor::Property::SCALE_X:
+ property = &mNode->mScale;
+ break;
+
+ case Dali::Actor::Property::SCALE_Y:
+ property = &mNode->mScale;
+ break;
+
+ case Dali::Actor::Property::SCALE_Z:
+ property = &mNode->mScale;
+ break;
+
+ case Dali::Actor::Property::VISIBLE:
+ property = &mNode->mVisible;
+ break;
+
+ case Dali::Actor::Property::COLOR:
+ property = &mNode->mColor;
+ break;
+
+ case Dali::Actor::Property::COLOR_RED:
+ property = &mNode->mColor;
+ break;
+
+ case Dali::Actor::Property::COLOR_GREEN:
+ property = &mNode->mColor;
+ break;
+
+ case Dali::Actor::Property::COLOR_BLUE:
+ property = &mNode->mColor;
+ break;
+
+ case Dali::Actor::Property::COLOR_ALPHA:
+ case Dali::DevelActor::Property::OPACITY:
+ property = &mNode->mColor;
+ break;
+
+ default:
+ break;
}
+ }
- case Dali::Actor::Property::SIZE_HEIGHT:
+ return property;
+}
+
+const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
+{
+ const PropertyInputImpl* property( NULL );
+
+ // This method should only return a property of an object connected to the scene-graph
+ if( !OnStage() )
+ {
+ return property;
+ }
+
+ if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
+ {
+ AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
+ DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
+
+ property = animatable->GetSceneGraphProperty();
+ }
+ else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
+ ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
+ {
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
+ property = custom->GetSceneGraphProperty();
+ }
+ else if( NULL != mNode )
+ {
+ switch( index )
{
- if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
- {
- // Should return preferred size if size is fixed as set by SetSize
- value = GetPreferredSize().height;
- }
- else
+ case Dali::Actor::Property::PARENT_ORIGIN:
+ property = &mNode->mParentOrigin;
+ break;
+
+ case Dali::Actor::Property::PARENT_ORIGIN_X:
+ property = &mNode->mParentOrigin;
+ break;
+
+ case Dali::Actor::Property::PARENT_ORIGIN_Y:
+ property = &mNode->mParentOrigin;
+ break;
+
+ case Dali::Actor::Property::PARENT_ORIGIN_Z:
+ property = &mNode->mParentOrigin;
+ break;
+
+ case Dali::Actor::Property::ANCHOR_POINT:
+ property = &mNode->mAnchorPoint;
+ break;
+
+ case Dali::Actor::Property::ANCHOR_POINT_X:
+ property = &mNode->mAnchorPoint;
+ break;
+
+ case Dali::Actor::Property::ANCHOR_POINT_Y:
+ property = &mNode->mAnchorPoint;
+ break;
+
+ case Dali::Actor::Property::ANCHOR_POINT_Z:
+ property = &mNode->mAnchorPoint;
+ break;
+
+ case Dali::Actor::Property::SIZE:
+ property = &mNode->mSize;
+ break;
+
+ case Dali::Actor::Property::SIZE_WIDTH:
+ property = &mNode->mSize;
+ break;
+
+ case Dali::Actor::Property::SIZE_HEIGHT:
+ property = &mNode->mSize;
+ break;
+
+ case Dali::Actor::Property::SIZE_DEPTH:
+ property = &mNode->mSize;
+ break;
+
+ case Dali::Actor::Property::POSITION:
+ property = &mNode->mPosition;
+ break;
+
+ case Dali::Actor::Property::POSITION_X:
+ property = &mNode->mPosition;
+ break;
+
+ case Dali::Actor::Property::POSITION_Y:
+ property = &mNode->mPosition;
+ break;
+
+ case Dali::Actor::Property::POSITION_Z:
+ property = &mNode->mPosition;
+ break;
+
+ case Dali::Actor::Property::WORLD_POSITION:
+ property = &mNode->mWorldPosition;
+ break;
+
+ case Dali::Actor::Property::WORLD_POSITION_X:
+ property = &mNode->mWorldPosition;
+ break;
+
+ case Dali::Actor::Property::WORLD_POSITION_Y:
+ property = &mNode->mWorldPosition;
+ break;
+
+ case Dali::Actor::Property::WORLD_POSITION_Z:
+ property = &mNode->mWorldPosition;
+ break;
+
+ case Dali::Actor::Property::ORIENTATION:
+ property = &mNode->mOrientation;
+ break;
+
+ case Dali::Actor::Property::WORLD_ORIENTATION:
+ property = &mNode->mWorldOrientation;
+ break;
+
+ case Dali::Actor::Property::SCALE:
+ property = &mNode->mScale;
+ break;
+
+ case Dali::Actor::Property::SCALE_X:
+ property = &mNode->mScale;
+ break;
+
+ case Dali::Actor::Property::SCALE_Y:
+ property = &mNode->mScale;
+ break;
+
+ case Dali::Actor::Property::SCALE_Z:
+ property = &mNode->mScale;
+ break;
+
+ case Dali::Actor::Property::WORLD_SCALE:
+ property = &mNode->mWorldScale;
+ break;
+
+ case Dali::Actor::Property::VISIBLE:
+ property = &mNode->mVisible;
+ break;
+
+ case Dali::Actor::Property::COLOR:
+ property = &mNode->mColor;
+ break;
+
+ case Dali::Actor::Property::COLOR_RED:
+ property = &mNode->mColor;
+ break;
+
+ case Dali::Actor::Property::COLOR_GREEN:
+ property = &mNode->mColor;
+ break;
+
+ case Dali::Actor::Property::COLOR_BLUE:
+ property = &mNode->mColor;
+ break;
+
+ case Dali::Actor::Property::COLOR_ALPHA:
+ case Dali::DevelActor::Property::OPACITY:
{
- value = GetTargetSize().height;
+ property = &mNode->mColor;
+ break;
}
- break;
- }
-
- case Dali::Actor::Property::SIZE_DEPTH:
- {
- value = GetTargetSize().depth;
- break;
- }
- case Dali::Actor::Property::POSITION:
- {
- value = GetTargetPosition();
- break;
- }
+ case Dali::Actor::Property::WORLD_COLOR:
+ property = &mNode->mWorldColor;
+ break;
- case Dali::Actor::Property::POSITION_X:
- {
- value = GetTargetPosition().x;
- break;
- }
+ case Dali::Actor::Property::WORLD_MATRIX:
+ property = &mNode->mWorldMatrix;
+ break;
- case Dali::Actor::Property::POSITION_Y:
- {
- value = GetTargetPosition().y;
- break;
+ default:
+ break;
}
+ }
- case Dali::Actor::Property::POSITION_Z:
- {
- value = GetTargetPosition().z;
- break;
- }
+ return property;
+}
- case Dali::Actor::Property::WORLD_POSITION:
- {
- value = GetCurrentWorldPosition();
- break;
- }
+int Actor::GetPropertyComponentIndex( Property::Index index ) const
+{
+ int componentIndex( Property::INVALID_COMPONENT_INDEX );
- case Dali::Actor::Property::WORLD_POSITION_X:
+ if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ // check whether the animatable property is registered already, if not then register one.
+ AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
+ if( animatableProperty )
{
- value = GetCurrentWorldPosition().x;
- break;
+ componentIndex = animatableProperty->componentIndex;
}
-
- case Dali::Actor::Property::WORLD_POSITION_Y:
+ }
+ else
+ {
+ switch( index )
{
- value = GetCurrentWorldPosition().y;
- break;
- }
+ case Dali::Actor::Property::PARENT_ORIGIN_X:
+ case Dali::Actor::Property::ANCHOR_POINT_X:
+ case Dali::Actor::Property::SIZE_WIDTH:
+ case Dali::Actor::Property::POSITION_X:
+ case Dali::Actor::Property::WORLD_POSITION_X:
+ case Dali::Actor::Property::SCALE_X:
+ case Dali::Actor::Property::COLOR_RED:
+ {
+ componentIndex = 0;
+ break;
+ }
- case Dali::Actor::Property::WORLD_POSITION_Z:
- {
- value = GetCurrentWorldPosition().z;
- break;
- }
+ case Dali::Actor::Property::PARENT_ORIGIN_Y:
+ case Dali::Actor::Property::ANCHOR_POINT_Y:
+ case Dali::Actor::Property::SIZE_HEIGHT:
+ case Dali::Actor::Property::POSITION_Y:
+ case Dali::Actor::Property::WORLD_POSITION_Y:
+ case Dali::Actor::Property::SCALE_Y:
+ case Dali::Actor::Property::COLOR_GREEN:
+ {
+ componentIndex = 1;
+ break;
+ }
- case Dali::Actor::Property::ORIENTATION:
- {
- value = GetCurrentOrientation();
- break;
- }
+ case Dali::Actor::Property::PARENT_ORIGIN_Z:
+ case Dali::Actor::Property::ANCHOR_POINT_Z:
+ case Dali::Actor::Property::SIZE_DEPTH:
+ case Dali::Actor::Property::POSITION_Z:
+ case Dali::Actor::Property::WORLD_POSITION_Z:
+ case Dali::Actor::Property::SCALE_Z:
+ case Dali::Actor::Property::COLOR_BLUE:
+ {
+ componentIndex = 2;
+ break;
+ }
- case Dali::Actor::Property::WORLD_ORIENTATION:
- {
- value = GetCurrentWorldOrientation();
- break;
- }
+ case Dali::Actor::Property::COLOR_ALPHA:
+ case Dali::DevelActor::Property::OPACITY:
+ {
+ componentIndex = 3;
+ break;
+ }
- case Dali::Actor::Property::SCALE:
- {
- value = GetCurrentScale();
- break;
+ default:
+ {
+ // Do nothing
+ break;
+ }
}
+ }
- case Dali::Actor::Property::SCALE_X:
- {
- value = GetCurrentScale().x;
- break;
- }
+ return componentIndex;
+}
- case Dali::Actor::Property::SCALE_Y:
- {
- value = GetCurrentScale().y;
- break;
- }
+void Actor::SetParent( Actor* parent )
+{
+ if( parent )
+ {
+ DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
- case Dali::Actor::Property::SCALE_Z:
- {
- value = GetCurrentScale().z;
- break;
- }
+ mParent = parent;
- case Dali::Actor::Property::WORLD_SCALE:
+ if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
+ parent->OnStage() )
{
- value = GetCurrentWorldScale();
- break;
+ // Instruct each actor to create a corresponding node in the scene graph
+ ConnectToStage( parent->GetHierarchyDepth() );
}
- case Dali::Actor::Property::VISIBLE:
- {
- value = IsVisible();
- break;
- }
+ // Resolve the name and index for the child properties if any
+ ResolveChildProperties();
+ }
+ else // parent being set to NULL
+ {
+ DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
- case Dali::Actor::Property::COLOR:
- {
- value = GetCurrentColor();
- break;
- }
+ mParent = NULL;
- case Dali::Actor::Property::COLOR_RED:
+ if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
+ OnStage() )
{
- value = GetCurrentColor().r;
- break;
- }
+ DALI_ASSERT_ALWAYS( mNode != NULL );
- case Dali::Actor::Property::COLOR_GREEN:
- {
- value = GetCurrentColor().g;
- break;
- }
+ if( NULL != mNode )
+ {
+ // Disconnect the Node & its children from the scene-graph.
+ DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
+ }
- case Dali::Actor::Property::COLOR_BLUE:
- {
- value = GetCurrentColor().b;
- break;
+ // Instruct each actor to discard pointers to the scene-graph
+ DisconnectFromStage();
}
+ }
+}
- case Dali::Actor::Property::COLOR_ALPHA:
- case Dali::DevelActor::Property::OPACITY:
- {
- value = GetCurrentColor().a;
- break;
- }
+SceneGraph::Node* Actor::CreateNode() const
+{
+ return Node::New();
+}
- case Dali::Actor::Property::WORLD_COLOR:
- {
- value = GetCurrentWorldColor();
- break;
- }
+bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
+{
+ bool done = false;
+ Actor* actor = dynamic_cast< Actor* >( object );
- case Dali::Actor::Property::WORLD_MATRIX:
+ if( actor )
+ {
+ if( 0 == actionName.compare( ACTION_SHOW ) )
{
- value = GetCurrentWorldMatrix();
- break;
+ actor->SetVisible( true );
+ done = true;
}
-
- case Dali::Actor::Property::NAME:
+ else if( 0 == actionName.compare( ACTION_HIDE ) )
{
- value = GetName();
- break;
+ actor->SetVisible( false );
+ done = true;
}
+ }
- case Dali::Actor::Property::SENSITIVE:
+ return done;
+}
+
+bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
+{
+ bool valueSet = true;
+
+ switch( index )
+ {
+ case Dali::Actor::Property::PARENT_ORIGIN:
{
- value = IsSensitive();
+ value = GetCurrentParentOrigin();
break;
}
- case Dali::Actor::Property::LEAVE_REQUIRED:
+ case Dali::Actor::Property::PARENT_ORIGIN_X:
{
- value = GetLeaveRequired();
+ value = GetCurrentParentOrigin().x;
break;
}
- case Dali::Actor::Property::INHERIT_POSITION:
+ case Dali::Actor::Property::PARENT_ORIGIN_Y:
{
- value = IsPositionInherited();
+ value = GetCurrentParentOrigin().y;
break;
}
- case Dali::Actor::Property::INHERIT_ORIENTATION:
+ case Dali::Actor::Property::PARENT_ORIGIN_Z:
{
- value = IsOrientationInherited();
+ value = GetCurrentParentOrigin().z;
break;
}
- case Dali::Actor::Property::INHERIT_SCALE:
+ case Dali::Actor::Property::ANCHOR_POINT:
{
- value = IsScaleInherited();
+ value = GetCurrentAnchorPoint();
break;
}
- case Dali::Actor::Property::COLOR_MODE:
+ case Dali::Actor::Property::ANCHOR_POINT_X:
{
- value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
+ value = GetCurrentAnchorPoint().x;
break;
}
- case Dali::Actor::Property::POSITION_INHERITANCE:
+ case Dali::Actor::Property::ANCHOR_POINT_Y:
{
- value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
+ value = GetCurrentAnchorPoint().y;
break;
}
- case Dali::Actor::Property::DRAW_MODE:
+ case Dali::Actor::Property::ANCHOR_POINT_Z:
{
- value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
+ value = GetCurrentAnchorPoint().z;
break;
}
- case Dali::Actor::Property::SIZE_MODE_FACTOR:
+ case Dali::Actor::Property::SIZE:
{
- value = GetSizeModeFactor();
+ value = GetTargetSize();
break;
}
- case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
+ case Dali::Actor::Property::SIZE_WIDTH:
{
- value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
+ value = GetTargetSize().width;
break;
}
- case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
+ case Dali::Actor::Property::SIZE_HEIGHT:
{
- value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
+ value = GetTargetSize().height;
break;
}
- case Dali::Actor::Property::SIZE_SCALE_POLICY:
+ case Dali::Actor::Property::SIZE_DEPTH:
{
- value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
+ value = GetTargetSize().depth;
break;
}
- case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
+ case Dali::Actor::Property::POSITION:
{
- value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
+ value = GetTargetPosition();
break;
}
- case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
+ case Dali::Actor::Property::POSITION_X:
{
- value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
+ value = GetTargetPosition().x;
break;
}
- case Dali::Actor::Property::PADDING:
+ case Dali::Actor::Property::POSITION_Y:
{
- Vector2 widthPadding = GetPadding( Dimension::WIDTH );
- Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
- value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
+ value = GetTargetPosition().y;
break;
}
- case Dali::Actor::Property::MINIMUM_SIZE:
+ case Dali::Actor::Property::POSITION_Z:
{
- value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
+ value = GetTargetPosition().z;
break;
}
- case Dali::Actor::Property::MAXIMUM_SIZE:
+ case Dali::Actor::Property::ORIENTATION:
{
- value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
+ value = mTargetOrientation;
break;
}
- case Dali::DevelActor::Property::SIBLING_ORDER:
+ case Dali::Actor::Property::SCALE:
{
- value = static_cast<int>(mSiblingOrder);
+ value = mTargetScale;
break;
}
- case Dali::Actor::Property::CLIPPING_MODE:
+ case Dali::Actor::Property::SCALE_X:
{
- value = mClippingMode;
+ value = mTargetScale.x;
break;
}
- case Dali::DevelActor::Property::SCREEN_POSITION:
+ case Dali::Actor::Property::SCALE_Y:
{
- value = GetCurrentScreenPosition();
+ value = mTargetScale.y;
break;
}
- case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
+ case Dali::Actor::Property::SCALE_Z:
{
- value = mPositionUsesAnchorPoint;
+ value = mTargetScale.z;
break;
}
- }
-
- return value;
-}
-
-const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
-{
- return mNode;
-}
-
-const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
-{
- // This method should only return an object connected to the scene-graph
- return OnStage() ? mNode : NULL;
-}
-
-const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
-{
- DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
-
- const PropertyBase* property( NULL );
-
- // This method should only return a property of an object connected to the scene-graph
- if( !OnStage() )
- {
- return property;
- }
-
- if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
- {
- AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
- DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
-
- property = animatable->GetSceneGraphProperty();
- }
- else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
- ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
- {
- CustomPropertyMetadata* custom = FindCustomProperty( index );
- DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
- property = custom->GetSceneGraphProperty();
- }
- else if( NULL != mNode )
- {
- switch( index )
+ case Dali::Actor::Property::VISIBLE:
{
- case Dali::Actor::Property::SIZE:
- property = &mNode->mSize;
- break;
-
- case Dali::Actor::Property::SIZE_WIDTH:
- property = &mNode->mSize;
- break;
-
- case Dali::Actor::Property::SIZE_HEIGHT:
- property = &mNode->mSize;
- break;
-
- case Dali::Actor::Property::SIZE_DEPTH:
- property = &mNode->mSize;
- break;
-
- case Dali::Actor::Property::POSITION:
- property = &mNode->mPosition;
- break;
-
- case Dali::Actor::Property::POSITION_X:
- property = &mNode->mPosition;
- break;
-
- case Dali::Actor::Property::POSITION_Y:
- property = &mNode->mPosition;
- break;
-
- case Dali::Actor::Property::POSITION_Z:
- property = &mNode->mPosition;
- break;
-
- case Dali::Actor::Property::ORIENTATION:
- property = &mNode->mOrientation;
- break;
-
- case Dali::Actor::Property::SCALE:
- property = &mNode->mScale;
- break;
-
- case Dali::Actor::Property::SCALE_X:
- property = &mNode->mScale;
- break;
-
- case Dali::Actor::Property::SCALE_Y:
- property = &mNode->mScale;
- break;
-
- case Dali::Actor::Property::SCALE_Z:
- property = &mNode->mScale;
- break;
-
- case Dali::Actor::Property::VISIBLE:
- property = &mNode->mVisible;
- break;
-
- case Dali::Actor::Property::COLOR:
- property = &mNode->mColor;
- break;
-
- case Dali::Actor::Property::COLOR_RED:
- property = &mNode->mColor;
- break;
-
- case Dali::Actor::Property::COLOR_GREEN:
- property = &mNode->mColor;
- break;
-
- case Dali::Actor::Property::COLOR_BLUE:
- property = &mNode->mColor;
- break;
-
- case Dali::Actor::Property::COLOR_ALPHA:
- case Dali::DevelActor::Property::OPACITY:
- property = &mNode->mColor;
- break;
-
- default:
- break;
- }
- }
-
- return property;
-}
-
-const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
-{
- const PropertyInputImpl* property( NULL );
-
- // This method should only return a property of an object connected to the scene-graph
- if( !OnStage() )
- {
- return property;
- }
-
- if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
- {
- AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
- DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
-
- property = animatable->GetSceneGraphProperty();
- }
- else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
- ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
- {
- CustomPropertyMetadata* custom = FindCustomProperty( index );
- DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
- property = custom->GetSceneGraphProperty();
- }
- else if( NULL != mNode )
- {
- switch( index )
+ value = mVisible;
+ break;
+ }
+
+ case Dali::Actor::Property::COLOR:
{
- case Dali::Actor::Property::PARENT_ORIGIN:
- property = &mNode->mParentOrigin;
- break;
+ value = mTargetColor;
+ break;
+ }
- case Dali::Actor::Property::PARENT_ORIGIN_X:
- property = &mNode->mParentOrigin;
- break;
+ case Dali::Actor::Property::COLOR_RED:
+ {
+ value = mTargetColor.r;
+ break;
+ }
- case Dali::Actor::Property::PARENT_ORIGIN_Y:
- property = &mNode->mParentOrigin;
- break;
+ case Dali::Actor::Property::COLOR_GREEN:
+ {
+ value = mTargetColor.g;
+ break;
+ }
- case Dali::Actor::Property::PARENT_ORIGIN_Z:
- property = &mNode->mParentOrigin;
- break;
+ case Dali::Actor::Property::COLOR_BLUE:
+ {
+ value = mTargetColor.b;
+ break;
+ }
- case Dali::Actor::Property::ANCHOR_POINT:
- property = &mNode->mAnchorPoint;
- break;
+ case Dali::Actor::Property::COLOR_ALPHA:
+ case Dali::DevelActor::Property::OPACITY:
+ {
+ value = mTargetColor.a;
+ break;
+ }
- case Dali::Actor::Property::ANCHOR_POINT_X:
- property = &mNode->mAnchorPoint;
- break;
+ case Dali::Actor::Property::NAME:
+ {
+ value = GetName();
+ break;
+ }
- case Dali::Actor::Property::ANCHOR_POINT_Y:
- property = &mNode->mAnchorPoint;
- break;
+ case Dali::Actor::Property::SENSITIVE:
+ {
+ value = IsSensitive();
+ break;
+ }
- case Dali::Actor::Property::ANCHOR_POINT_Z:
- property = &mNode->mAnchorPoint;
- break;
+ case Dali::Actor::Property::LEAVE_REQUIRED:
+ {
+ value = GetLeaveRequired();
+ break;
+ }
- case Dali::Actor::Property::SIZE:
- property = &mNode->mSize;
- break;
+ case Dali::Actor::Property::INHERIT_POSITION:
+ {
+ value = IsPositionInherited();
+ break;
+ }
- case Dali::Actor::Property::SIZE_WIDTH:
- property = &mNode->mSize;
- break;
+ case Dali::Actor::Property::INHERIT_ORIENTATION:
+ {
+ value = IsOrientationInherited();
+ break;
+ }
- case Dali::Actor::Property::SIZE_HEIGHT:
- property = &mNode->mSize;
- break;
+ case Dali::Actor::Property::INHERIT_SCALE:
+ {
+ value = IsScaleInherited();
+ break;
+ }
- case Dali::Actor::Property::SIZE_DEPTH:
- property = &mNode->mSize;
- break;
+ case Dali::Actor::Property::COLOR_MODE:
+ {
+ value = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT );
+ break;
+ }
- case Dali::Actor::Property::POSITION:
- property = &mNode->mPosition;
- break;
+ case Dali::Actor::Property::POSITION_INHERITANCE:
+ {
+ value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT );
+ break;
+ }
- case Dali::Actor::Property::POSITION_X:
- property = &mNode->mPosition;
- break;
+ case Dali::Actor::Property::DRAW_MODE:
+ {
+ value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT );
+ break;
+ }
- case Dali::Actor::Property::POSITION_Y:
- property = &mNode->mPosition;
- break;
+ case Dali::Actor::Property::SIZE_MODE_FACTOR:
+ {
+ value = GetSizeModeFactor();
+ break;
+ }
- case Dali::Actor::Property::POSITION_Z:
- property = &mNode->mPosition;
- break;
+ case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
+ {
+ value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
+ break;
+ }
- case Dali::Actor::Property::WORLD_POSITION:
- property = &mNode->mWorldPosition;
- break;
+ case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
+ {
+ value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT );
+ break;
+ }
- case Dali::Actor::Property::WORLD_POSITION_X:
- property = &mNode->mWorldPosition;
- break;
+ case Dali::Actor::Property::SIZE_SCALE_POLICY:
+ {
+ value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT );
+ break;
+ }
- case Dali::Actor::Property::WORLD_POSITION_Y:
- property = &mNode->mWorldPosition;
- break;
+ case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
+ {
+ value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT );
+ break;
+ }
- case Dali::Actor::Property::WORLD_POSITION_Z:
- property = &mNode->mWorldPosition;
- break;
+ case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
+ {
+ value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH );
+ break;
+ }
- case Dali::Actor::Property::ORIENTATION:
- property = &mNode->mOrientation;
- break;
+ case Dali::Actor::Property::PADDING:
+ {
+ Vector2 widthPadding = GetPadding( Dimension::WIDTH );
+ Vector2 heightPadding = GetPadding( Dimension::HEIGHT );
+ value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
+ break;
+ }
- case Dali::Actor::Property::WORLD_ORIENTATION:
- property = &mNode->mWorldOrientation;
- break;
+ case Dali::Actor::Property::MINIMUM_SIZE:
+ {
+ value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) );
+ break;
+ }
- case Dali::Actor::Property::SCALE:
- property = &mNode->mScale;
- break;
+ case Dali::Actor::Property::MAXIMUM_SIZE:
+ {
+ value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) );
+ break;
+ }
- case Dali::Actor::Property::SCALE_X:
- property = &mNode->mScale;
- break;
+ case Dali::Actor::Property::CLIPPING_MODE:
+ {
+ value = mClippingMode;
+ break;
+ }
- case Dali::Actor::Property::SCALE_Y:
- property = &mNode->mScale;
- break;
+ case Dali::DevelActor::Property::SIBLING_ORDER:
+ {
+ value = static_cast<int>(mSiblingOrder);
+ break;
+ }
- case Dali::Actor::Property::SCALE_Z:
- property = &mNode->mScale;
- break;
+ case Dali::DevelActor::Property::SCREEN_POSITION:
+ {
+ value = GetCurrentScreenPosition();
+ break;
+ }
- case Dali::Actor::Property::WORLD_SCALE:
- property = &mNode->mWorldScale;
- break;
+ case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT:
+ {
+ value = mPositionUsesAnchorPoint;
+ break;
+ }
- case Dali::Actor::Property::VISIBLE:
- property = &mNode->mVisible;
- break;
+ default:
+ {
+ // Must be a scene-graph only property
+ valueSet = false;
+ break;
+ }
+ }
- case Dali::Actor::Property::COLOR:
- property = &mNode->mColor;
- break;
+ return valueSet;
+}
- case Dali::Actor::Property::COLOR_RED:
- property = &mNode->mColor;
- break;
+bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const
+{
+ bool valueSet = true;
- case Dali::Actor::Property::COLOR_GREEN:
- property = &mNode->mColor;
- break;
+ switch( index )
+ {
+ case Dali::Actor::Property::SIZE:
+ {
+ value = GetCurrentSize();
+ break;
+ }
- case Dali::Actor::Property::COLOR_BLUE:
- property = &mNode->mColor;
- break;
+ case Dali::Actor::Property::SIZE_WIDTH:
+ {
+ value = GetCurrentSize().width;
+ break;
+ }
- case Dali::Actor::Property::COLOR_ALPHA:
- case Dali::DevelActor::Property::OPACITY:
- {
- property = &mNode->mColor;
- break;
- }
+ case Dali::Actor::Property::SIZE_HEIGHT:
+ {
+ value = GetCurrentSize().height;
+ break;
+ }
- case Dali::Actor::Property::WORLD_COLOR:
- property = &mNode->mWorldColor;
- break;
+ case Dali::Actor::Property::SIZE_DEPTH:
+ {
+ value = GetCurrentSize().depth;
+ break;
+ }
- case Dali::Actor::Property::WORLD_MATRIX:
- property = &mNode->mWorldMatrix;
- break;
+ case Dali::Actor::Property::POSITION:
+ {
+ value = GetCurrentPosition();
+ break;
+ }
- default:
- break;
+ case Dali::Actor::Property::POSITION_X:
+ {
+ value = GetCurrentPosition().x;
+ break;
}
- }
- return property;
-}
+ case Dali::Actor::Property::POSITION_Y:
+ {
+ value = GetCurrentPosition().y;
+ break;
+ }
-int Actor::GetPropertyComponentIndex( Property::Index index ) const
-{
- int componentIndex( Property::INVALID_COMPONENT_INDEX );
+ case Dali::Actor::Property::POSITION_Z:
+ {
+ value = GetCurrentPosition().z;
+ break;
+ }
- if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
- {
- // check whether the animatable property is registered already, if not then register one.
- AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty(index);
- if( animatableProperty )
+ case Dali::Actor::Property::WORLD_POSITION:
{
- componentIndex = animatableProperty->componentIndex;
+ value = GetCurrentWorldPosition();
+ break;
}
- }
- else
- {
- switch( index )
+
+ case Dali::Actor::Property::WORLD_POSITION_X:
{
- case Dali::Actor::Property::PARENT_ORIGIN_X:
- case Dali::Actor::Property::ANCHOR_POINT_X:
- case Dali::Actor::Property::SIZE_WIDTH:
- case Dali::Actor::Property::POSITION_X:
- case Dali::Actor::Property::WORLD_POSITION_X:
- case Dali::Actor::Property::SCALE_X:
- case Dali::Actor::Property::COLOR_RED:
- {
- componentIndex = 0;
- break;
- }
+ value = GetCurrentWorldPosition().x;
+ break;
+ }
- case Dali::Actor::Property::PARENT_ORIGIN_Y:
- case Dali::Actor::Property::ANCHOR_POINT_Y:
- case Dali::Actor::Property::SIZE_HEIGHT:
- case Dali::Actor::Property::POSITION_Y:
- case Dali::Actor::Property::WORLD_POSITION_Y:
- case Dali::Actor::Property::SCALE_Y:
- case Dali::Actor::Property::COLOR_GREEN:
- {
- componentIndex = 1;
- break;
- }
+ case Dali::Actor::Property::WORLD_POSITION_Y:
+ {
+ value = GetCurrentWorldPosition().y;
+ break;
+ }
- case Dali::Actor::Property::PARENT_ORIGIN_Z:
- case Dali::Actor::Property::ANCHOR_POINT_Z:
- case Dali::Actor::Property::SIZE_DEPTH:
- case Dali::Actor::Property::POSITION_Z:
- case Dali::Actor::Property::WORLD_POSITION_Z:
- case Dali::Actor::Property::SCALE_Z:
- case Dali::Actor::Property::COLOR_BLUE:
- {
- componentIndex = 2;
- break;
- }
+ case Dali::Actor::Property::WORLD_POSITION_Z:
+ {
+ value = GetCurrentWorldPosition().z;
+ break;
+ }
- case Dali::Actor::Property::COLOR_ALPHA:
- case Dali::DevelActor::Property::OPACITY:
- {
- componentIndex = 3;
- break;
- }
+ case Dali::Actor::Property::ORIENTATION:
+ {
+ value = GetCurrentOrientation();
+ break;
+ }
- default:
- {
- // Do nothing
- break;
- }
+ case Dali::Actor::Property::WORLD_ORIENTATION:
+ {
+ value = GetCurrentWorldOrientation();
+ break;
}
- }
- return componentIndex;
-}
+ case Dali::Actor::Property::SCALE:
+ {
+ value = GetCurrentScale();
+ break;
+ }
-void Actor::SetParent( Actor* parent )
-{
- if( parent )
- {
- DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
+ case Dali::Actor::Property::SCALE_X:
+ {
+ value = GetCurrentScale().x;
+ break;
+ }
- mParent = parent;
+ case Dali::Actor::Property::SCALE_Y:
+ {
+ value = GetCurrentScale().y;
+ break;
+ }
- if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
- parent->OnStage() )
+ case Dali::Actor::Property::SCALE_Z:
{
- // Instruct each actor to create a corresponding node in the scene graph
- ConnectToStage( parent->GetHierarchyDepth() );
+ value = GetCurrentScale().z;
+ break;
}
- // Resolve the name and index for the child properties if any
- ResolveChildProperties();
- }
- else // parent being set to NULL
- {
- DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
+ case Dali::Actor::Property::WORLD_SCALE:
+ {
+ value = GetCurrentWorldScale();
+ break;
+ }
- mParent = NULL;
+ case Dali::Actor::Property::COLOR:
+ {
+ value = GetCurrentColor();
+ break;
+ }
- if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
- OnStage() )
+ case Dali::Actor::Property::COLOR_RED:
{
- DALI_ASSERT_ALWAYS( mNode != NULL );
+ value = GetCurrentColor().r;
+ break;
+ }
- if( NULL != mNode )
- {
- // Disconnect the Node & its children from the scene-graph.
- DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode );
- }
+ case Dali::Actor::Property::COLOR_GREEN:
+ {
+ value = GetCurrentColor().g;
+ break;
+ }
- // Instruct each actor to discard pointers to the scene-graph
- DisconnectFromStage();
+ case Dali::Actor::Property::COLOR_BLUE:
+ {
+ value = GetCurrentColor().b;
+ break;
}
- }
-}
-SceneGraph::Node* Actor::CreateNode() const
-{
- return Node::New();
-}
+ case Dali::Actor::Property::COLOR_ALPHA:
+ case Dali::DevelActor::Property::OPACITY:
+ {
+ value = GetCurrentColor().a;
+ break;
+ }
-bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
-{
- bool done = false;
- Actor* actor = dynamic_cast< Actor* >( object );
+ case Dali::Actor::Property::WORLD_COLOR:
+ {
+ value = GetCurrentWorldColor();
+ break;
+ }
- if( actor )
- {
- if( 0 == actionName.compare( ACTION_SHOW ) )
+ case Dali::Actor::Property::WORLD_MATRIX:
{
- actor->SetVisible( true );
- done = true;
+ value = GetCurrentWorldMatrix();
+ break;
}
- else if( 0 == actionName.compare( ACTION_HIDE ) )
+
+ default:
{
- actor->SetVisible( false );
- done = true;
+ // Must be an event-side only property
+ valueSet = false;
+ break;
}
}
- return done;
+ return valueSet;
}
void Actor::EnsureRelayoutData()
float Actor::GetSize( Dimension::Type dimension ) const
{
- return GetDimensionValue( GetTargetSize(), dimension );
+ return GetDimensionValue( mTargetSize, dimension );
}
float Actor::GetNaturalSize( Dimension::Type dimension ) const
// relayout container afterwards, the dirty flags would still be clear...
// causing a relayout to be skipped. Here we force any actors added to the
// container to be relayed out.
- if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
+ DALI_LOG_TIMER_START( NegSizeTimer1 );
+
+ if( GetUseAssignedSize(Dimension::WIDTH ) )
{
- SetLayoutNegotiated(false, Dimension::WIDTH);
+ SetLayoutNegotiated( false, Dimension::WIDTH );
}
- if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
+ if( GetUseAssignedSize( Dimension::HEIGHT ) )
{
- SetLayoutNegotiated(false, Dimension::HEIGHT);
+ SetLayoutNegotiated( false, Dimension::HEIGHT );
}
// Do the negotiation
SetNegotiatedSize( container );
// Negotiate down to children
- const Vector2 newBounds = GetTargetSize().GetVectorXY();
+ const Vector2 newBounds = mTargetSize.GetVectorXY();
for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
{
// Forces children that have already been laid out to be relayed out
// if they have assigned size during relayout.
- if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
+ if( child->GetUseAssignedSize(Dimension::WIDTH) )
{
child->SetLayoutNegotiated(false, Dimension::WIDTH);
child->SetLayoutDirty(true, Dimension::WIDTH);
}
- if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
+
+ if( child->GetUseAssignedSize(Dimension::HEIGHT) )
{
child->SetLayoutNegotiated(false, Dimension::HEIGHT);
child->SetLayoutDirty(true, Dimension::HEIGHT);
container.Add( Dali::Actor( child.Get() ), newBounds );
}
}
+ DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
+}
+
+void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
+{
+ if( mRelayoutData )
+ {
+ for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
+ {
+ if( dimension & ( 1 << i ) )
+ {
+ mRelayoutData->useAssignedSize[ i ] = use;
+ }
+ }
+ }
+}
+
+bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
+{
+ if ( mRelayoutData )
+ {
+ // If more than one dimension is requested, just return the first one found
+ for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
+ {
+ if( dimension & ( 1 << i ) )
+ {
+ return mRelayoutData->useAssignedSize[ i ];
+ }
+ }
+ }
+
+ return false;
}
void Actor::RelayoutRequest( Dimension::Type dimension )
void Actor::SetSiblingOrder( unsigned int order )
{
mSiblingOrder = std::min( order, static_cast<unsigned int>( DevelLayer::SIBLING_ORDER_MULTIPLIER ) );
+
if( mIsOnStage )
{
- SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
+ StagePtr stage = Stage::GetCurrent();
+ if( stage )
+ {
+ stage->RequestRebuildDepthTree();
+ }
}
}