2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/actor-impl.h>
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/common/constants.h>
29 #include <dali/public-api/math/vector2.h>
30 #include <dali/public-api/math/vector3.h>
31 #include <dali/public-api/math/radian.h>
32 #include <dali/public-api/object/type-registry.h>
33 #include <dali/public-api/scripting/scripting.h>
35 #include <dali/internal/common/internal-constants.h>
36 #include <dali/internal/event/render-tasks/render-task-impl.h>
37 #include <dali/internal/event/actors/camera-actor-impl.h>
38 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
39 #include <dali/internal/event/common/property-index-ranges.h>
40 #include <dali/internal/event/common/stage-impl.h>
41 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
42 #include <dali/internal/event/animation/constraint-impl.h>
43 #include <dali/internal/event/common/projection.h>
44 #include <dali/internal/update/common/animatable-property.h>
45 #include <dali/internal/update/common/property-owner-messages.h>
46 #include <dali/internal/update/nodes/node-messages.h>
47 #include <dali/internal/update/nodes/node-declarations.h>
48 #include <dali/internal/update/animation/scene-graph-constraint.h>
49 #include <dali/internal/event/events/actor-gesture-data.h>
50 #include <dali/internal/common/message.h>
51 #include <dali/integration-api/debug.h>
53 #ifdef DYNAMICS_SUPPORT
54 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
55 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
57 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
60 using Dali::Internal::SceneGraph::Node;
61 using Dali::Internal::SceneGraph::AnimatableProperty;
62 using Dali::Internal::SceneGraph::PropertyBase;
69 const Property::Index Actor::PARENT_ORIGIN = 0;
70 const Property::Index Actor::PARENT_ORIGIN_X = 1;
71 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
72 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
73 const Property::Index Actor::ANCHOR_POINT = 4;
74 const Property::Index Actor::ANCHOR_POINT_X = 5;
75 const Property::Index Actor::ANCHOR_POINT_Y = 6;
76 const Property::Index Actor::ANCHOR_POINT_Z = 7;
77 const Property::Index Actor::SIZE = 8;
78 const Property::Index Actor::SIZE_WIDTH = 9;
79 const Property::Index Actor::SIZE_HEIGHT = 10;
80 const Property::Index Actor::SIZE_DEPTH = 11;
81 const Property::Index Actor::POSITION = 12;
82 const Property::Index Actor::POSITION_X = 13;
83 const Property::Index Actor::POSITION_Y = 14;
84 const Property::Index Actor::POSITION_Z = 15;
85 const Property::Index Actor::WORLD_POSITION = 16;
86 const Property::Index Actor::WORLD_POSITION_X = 17;
87 const Property::Index Actor::WORLD_POSITION_Y = 18;
88 const Property::Index Actor::WORLD_POSITION_Z = 19;
89 const Property::Index Actor::ROTATION = 20;
90 const Property::Index Actor::WORLD_ROTATION = 21;
91 const Property::Index Actor::SCALE = 22;
92 const Property::Index Actor::SCALE_X = 23;
93 const Property::Index Actor::SCALE_Y = 24;
94 const Property::Index Actor::SCALE_Z = 25;
95 const Property::Index Actor::WORLD_SCALE = 26;
96 const Property::Index Actor::VISIBLE = 27;
97 const Property::Index Actor::COLOR = 28;
98 const Property::Index Actor::COLOR_RED = 29;
99 const Property::Index Actor::COLOR_GREEN = 30;
100 const Property::Index Actor::COLOR_BLUE = 31;
101 const Property::Index Actor::COLOR_ALPHA = 32;
102 const Property::Index Actor::WORLD_COLOR = 33;
103 const Property::Index Actor::WORLD_MATRIX = 34;
104 const Property::Index Actor::NAME = 35;
105 const Property::Index Actor::SENSITIVE = 36;
106 const Property::Index Actor::LEAVE_REQUIRED = 37;
107 const Property::Index Actor::INHERIT_ROTATION = 38;
108 const Property::Index Actor::INHERIT_SCALE = 39;
109 const Property::Index Actor::COLOR_MODE = 40;
110 const Property::Index Actor::POSITION_INHERITANCE = 41;
111 const Property::Index Actor::DRAW_MODE = 42;
113 namespace // unnamed namespace
117 * We want to discourage the use of property strings (minimize string comparisons),
118 * particularly for the default properties.
120 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
122 // Name Type writable animatable constraint-input
123 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
124 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
125 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
126 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
127 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
128 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
129 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
130 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
131 { "size", Property::VECTOR3, true, true, true }, // SIZE
132 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
133 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
134 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
135 { "position", Property::VECTOR3, true, true, true }, // POSITION
136 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
137 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
138 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
139 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
140 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
141 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
142 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
143 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
144 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
145 { "scale", Property::VECTOR3, true, true, true }, // SCALE
146 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
147 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
148 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
149 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
150 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
151 { "color", Property::VECTOR4, true, true, true }, // COLOR
152 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
153 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
154 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
155 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
156 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
157 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
158 { "name", Property::STRING, true, false, false }, // NAME
159 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
160 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
161 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
162 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
163 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
164 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
165 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
167 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
169 } // unnamed namespace
174 unsigned int Actor::mActorCounter = 0;
175 ActorContainer Actor::mNullChildren;
177 #ifdef DYNAMICS_SUPPORT
179 // Encapsulate actor related dynamics data
182 DynamicsData( Actor* slotOwner )
183 : slotDelegate( slotOwner )
187 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
188 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
190 DynamicsBodyPtr body;
191 JointContainer joints;
192 ReferencedJointContainer referencedJoints;
194 SlotDelegate< Actor > slotDelegate;
197 #endif // DYNAMICS_SUPPORT
202 using namespace Dali;
204 BaseHandle CreateActor()
206 return Dali::Actor::New();
209 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
211 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
212 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
213 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
214 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
216 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
217 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
221 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
223 ActorPtr Actor::New()
225 ActorPtr actor( new Actor( BASIC ) );
227 // Second-phase construction
233 const std::string& Actor::GetName() const
238 void Actor::SetName(const std::string& name)
244 // ATTENTION: string for debug purposes is not thread safe.
245 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
249 unsigned int Actor::GetId() const
254 void Actor::Attach( ActorAttachment& attachment )
256 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
260 attachment.Connect();
263 mAttachment = ActorAttachmentPtr(&attachment);
266 ActorAttachmentPtr Actor::GetAttachment()
271 bool Actor::OnStage() const
276 Dali::Layer Actor::GetLayer()
280 // Short-circuit for Layer derived actors
283 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
286 // Find the immediate Layer parent
287 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
289 if( parent->IsLayer() )
291 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
298 void Actor::Add(Actor& child)
300 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
301 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
305 mChildren = new ActorContainer;
308 Actor* const oldParent( child.mParent );
310 // child might already be ours
311 if( this != oldParent )
313 // if we already have parent, unparent us first
316 oldParent->Remove( child ); // This causes OnChildRemove callback
319 // Guard against Add() during previous OnChildRemove callback
320 if ( !child.mParent )
322 // Do this first, since user callbacks from within SetParent() may need to remove child
323 mChildren->push_back(Dali::Actor(&child));
325 // SetParent asserts that child can be added
326 child.SetParent(this);
328 // Notification for derived classes
334 void Actor::Insert(unsigned int index, Actor& child)
336 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
337 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
341 mChildren = new ActorContainer;
344 Actor* const oldParent( child.mParent );
346 // since an explicit position has been given, always insert, even if already a child
349 oldParent->Remove( child ); // This causes OnChildRemove callback
352 // Guard against Add() during previous OnChildRemove callback
353 if ( !child.mParent )
355 // Do this first, since user callbacks from within SetParent() may need to remove child
356 if (index < child.GetChildCount())
358 ActorIter it = mChildren->begin();
359 std::advance(it, index);
360 mChildren->insert(it, Dali::Actor(&child));
364 mChildren->push_back(Dali::Actor(&child));
366 // SetParent asserts that child can be added
367 child.SetParent(this, index);
369 // Notification for derived classes
374 void Actor::Remove(Actor& child)
376 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
386 // Find the child in mChildren, and unparent it
387 ActorIter end = mChildren->end();
388 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
390 Actor& actor = GetImplementation(*iter);
392 if( &actor == &child )
394 // Keep handle for OnChildRemove notification
395 removed = Dali::Actor( &actor );
397 // Do this first, since user callbacks from within SetParent() may need to add the child
398 mChildren->erase(iter);
400 DALI_ASSERT_DEBUG( actor.GetParent() == this );
401 actor.SetParent( NULL );
409 // Notification for derived classes
410 OnChildRemove( GetImplementation(removed) );
414 void Actor::Unparent()
418 mParent->Remove( *this );
422 unsigned int Actor::GetChildCount() const
424 return ( NULL != mChildren ) ? mChildren->size() : 0;
427 Dali::Actor Actor::GetChildAt(unsigned int index) const
429 DALI_ASSERT_ALWAYS( index < GetChildCount() );
431 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
434 ActorContainer Actor::GetChildren()
436 if( NULL != mChildren )
441 // return copy of mNullChildren
442 return mNullChildren;
445 const ActorContainer& Actor::GetChildren() const
447 if( NULL != mChildren )
452 // return const reference to mNullChildren
453 return mNullChildren;
456 ActorPtr Actor::FindChildByName(const std::string& actorName)
459 if (actorName == mName)
465 ActorIter end = mChildren->end();
466 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
468 child = GetImplementation(*iter).FindChildByName(actorName);
479 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
481 Dali::Actor child = DoGetChildByAlias(actorAlias);
483 // If not found then search by name.
486 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
489 child = Dali::Actor(child_ptr.Get());
496 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
498 Dali::Actor child = GetChildByAlias(actorAlias);
500 if (!child && mChildren )
502 ActorIter end = mChildren->end();
503 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
505 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
517 ActorPtr Actor::FindChildById(const unsigned int id)
526 ActorIter end = mChildren->end();
527 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
529 child = GetImplementation(*iter).FindChildById(id);
540 void Actor::SetParentOrigin( const Vector3& origin )
544 // mNode is being used in a separate thread; queue a message to set the value & base value
545 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
548 // Cache for event-thread access
551 // not allocated, check if different from default
552 if( ParentOrigin::DEFAULT != origin )
554 mParentOrigin = new Vector3( origin );
559 // check if different from current costs more than just set
560 *mParentOrigin = origin;
564 void Actor::SetParentOriginX( float x )
566 const Vector3& current = GetCurrentParentOrigin();
568 SetParentOrigin( Vector3( x, current.y, current.z ) );
571 void Actor::SetParentOriginY( float y )
573 const Vector3& current = GetCurrentParentOrigin();
575 SetParentOrigin( Vector3( current.x, y, current.z ) );
578 void Actor::SetParentOriginZ( float z )
580 const Vector3& current = GetCurrentParentOrigin();
582 SetParentOrigin( Vector3( current.x, current.y, z ) );
585 const Vector3& Actor::GetCurrentParentOrigin() const
587 // Cached for event-thread access
588 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
591 void Actor::SetAnchorPoint(const Vector3& anchor)
595 // mNode is being used in a separate thread; queue a message to set the value & base value
596 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
599 // Cache for event-thread access
602 // not allocated, check if different from default
603 if( AnchorPoint::DEFAULT != anchor )
605 mAnchorPoint = new Vector3( anchor );
610 // check if different from current costs more than just set
611 *mAnchorPoint = anchor;
615 void Actor::SetAnchorPointX( float x )
617 const Vector3& current = GetCurrentAnchorPoint();
619 SetAnchorPoint( Vector3( x, current.y, current.z ) );
622 void Actor::SetAnchorPointY( float y )
624 const Vector3& current = GetCurrentAnchorPoint();
626 SetAnchorPoint( Vector3( current.x, y, current.z ) );
629 void Actor::SetAnchorPointZ( float z )
631 const Vector3& current = GetCurrentAnchorPoint();
633 SetAnchorPoint( Vector3( current.x, current.y, z ) );
636 const Vector3& Actor::GetCurrentAnchorPoint() const
638 // Cached for event-thread access
639 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
642 void Actor::SetPosition(float x, float y)
644 SetPosition(Vector3(x, y, 0.0f));
647 void Actor::SetPosition(float x, float y, float z)
649 SetPosition(Vector3(x, y, z));
652 void Actor::SetPosition(const Vector3& position)
656 // mNode is being used in a separate thread; queue a message to set the value & base value
657 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
661 void Actor::SetX(float x)
665 // mNode is being used in a separate thread; queue a message to set the value & base value
666 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
670 void Actor::SetY(float y)
674 // mNode is being used in a separate thread; queue a message to set the value & base value
675 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
679 void Actor::SetZ(float z)
683 // mNode is being used in a separate thread; queue a message to set the value & base value
684 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
688 void Actor::MoveBy(const Vector3& distance)
692 // mNode is being used in a separate thread; queue a message to set the value & base value
693 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
697 const Vector3& Actor::GetCurrentPosition() const
701 // mNode is being used in a separate thread; copy the value from the previous update
702 return mNode->GetPosition(mStage->GetEventBufferIndex());
705 return Vector3::ZERO;
708 const Vector3& Actor::GetCurrentWorldPosition() const
712 // mNode is being used in a separate thread; copy the value from the previous update
713 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
716 return Vector3::ZERO;
719 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
721 // this flag is not animatable so keep the value
722 mPositionInheritanceMode = mode;
725 // mNode is being used in a separate thread; queue a message to set the value
726 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
730 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
732 // Cached for event-thread access
733 return mPositionInheritanceMode;
736 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
738 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
739 normalizedAxis.Normalize();
741 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
743 SetRotation(rotation);
746 void Actor::SetRotation(const Quaternion& rotation)
750 // mNode is being used in a separate thread; queue a message to set the value & base value
751 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
755 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
759 // mNode is being used in a separate thread; queue a message to set the value & base value
760 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
764 void Actor::RotateBy(const Quaternion& relativeRotation)
768 // mNode is being used in a separate thread; queue a message to set the value & base value
769 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
773 const Quaternion& Actor::GetCurrentRotation() const
777 // mNode is being used in a separate thread; copy the value from the previous update
778 return mNode->GetRotation(mStage->GetEventBufferIndex());
781 return Quaternion::IDENTITY;
784 const Quaternion& Actor::GetCurrentWorldRotation() const
788 // mNode is being used in a separate thread; copy the value from the previous update
789 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
792 return Quaternion::IDENTITY;
795 void Actor::SetScale(float scale)
797 SetScale(Vector3(scale, scale, scale));
800 void Actor::SetScale(float x, float y, float z)
802 SetScale(Vector3(x, y, z));
805 void Actor::SetScale(const Vector3& scale)
809 // mNode is being used in a separate thread; queue a message to set the value & base value
810 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
814 void Actor::SetScaleX( float x )
818 // mNode is being used in a separate thread; queue a message to set the value & base value
819 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
823 void Actor::SetScaleY( float y )
827 // mNode is being used in a separate thread; queue a message to set the value & base value
828 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
832 void Actor::SetScaleZ( float z )
836 // mNode is being used in a separate thread; queue a message to set the value & base value
837 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
841 void Actor::SetInitialVolume(const Vector3& volume)
845 // mNode is being used in a separate thread; queue a message to set the value
846 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
850 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
854 // mNode is being used in a separate thread; queue a message to set the value
855 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
859 bool Actor::GetTransmitGeometryScaling() const
863 // mNode is being used in a separate thread; copy the value from the previous update
864 return mNode->GetTransmitGeometryScaling();
870 void Actor::ScaleBy(const Vector3& relativeScale)
874 // mNode is being used in a separate thread; queue a message to set the value & base value
875 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
879 const Vector3& Actor::GetCurrentScale() const
883 // mNode is being used in a separate thread; copy the value from the previous update
884 return mNode->GetScale(mStage->GetEventBufferIndex());
890 const Vector3& Actor::GetCurrentWorldScale() const
894 // mNode is being used in a separate thread; copy the value from the previous update
895 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
901 void Actor::SetInheritScale( bool inherit )
903 // non animateable so keep local copy
904 mInheritScale = inherit;
907 // mNode is being used in a separate thread; queue a message to set the value
908 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
912 bool Actor::IsScaleInherited() const
914 return mInheritScale;
917 Matrix Actor::GetCurrentWorldMatrix() const
921 // World matrix is no longer updated unless there is something observing the node.
922 // Need to calculate it from node's world position, rotation and scale:
923 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
924 Matrix worldMatrix(false);
925 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
926 mNode->GetWorldRotation( updateBufferIndex ),
927 mNode->GetWorldPosition( updateBufferIndex ) );
931 return Matrix::IDENTITY;
934 void Actor::SetVisible(bool visible)
938 // mNode is being used in a separate thread; queue a message to set the value & base value
939 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
943 bool Actor::IsVisible() const
947 // mNode is being used in a separate thread; copy the value from the previous update
948 return mNode->IsVisible( mStage->GetEventBufferIndex() );
954 void Actor::SetOpacity(float opacity)
958 // mNode is being used in a separate thread; queue a message to set the value & base value
959 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
963 void Actor::OpacityBy(float relativeOpacity)
967 // mNode is being used in a separate thread; queue a message to set the value & base value
968 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
972 float Actor::GetCurrentOpacity() const
976 // mNode is being used in a separate thread; copy the value from the previous update
977 return mNode->GetOpacity(mStage->GetEventBufferIndex());
983 const Vector4& Actor::GetCurrentWorldColor() const
987 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
993 void Actor::SetColor(const Vector4& color)
997 // mNode is being used in a separate thread; queue a message to set the value & base value
998 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
1002 void Actor::SetColorRed( float red )
1006 // mNode is being used in a separate thread; queue a message to set the value & base value
1007 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
1011 void Actor::SetColorGreen( float green )
1015 // mNode is being used in a separate thread; queue a message to set the value & base value
1016 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
1020 void Actor::SetColorBlue( float blue )
1024 // mNode is being used in a separate thread; queue a message to set the value & base value
1025 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
1029 void Actor::ColorBy(const Vector4& relativeColor)
1033 // mNode is being used in a separate thread; queue a message to set the value & base value
1034 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
1038 const Vector4& Actor::GetCurrentColor() const
1042 // mNode is being used in a separate thread; copy the value from the previous update
1043 return mNode->GetColor(mStage->GetEventBufferIndex());
1046 return Color::WHITE;
1049 void Actor::SetInheritRotation(bool inherit)
1051 // non animateable so keep local copy
1052 mInheritRotation = inherit;
1055 // mNode is being used in a separate thread; queue a message to set the value
1056 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1060 bool Actor::IsRotationInherited() const
1062 return mInheritRotation;
1065 void Actor::SetColorMode(ColorMode colorMode)
1067 // non animateable so keep local copy
1068 mColorMode = colorMode;
1071 // mNode is being used in a separate thread; queue a message to set the value
1072 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1076 ColorMode Actor::GetColorMode() const
1078 // we have cached copy
1082 void Actor::SetSize(float width, float height)
1084 SetSize( Vector2( width, height ) );
1087 void Actor::SetSize(float width, float height, float depth)
1089 SetSize( Vector3( width, height, depth ) );
1092 void Actor::SetSize(const Vector2& size)
1094 Vector3 volume( size );
1095 volume.z = std::min( size.width, size.height );
1099 void Actor::SetSize(const Vector3& size)
1103 // mNode is being used in a separate thread; queue a message to set the value & base value
1104 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1106 // Notification for derived classes
1109 // Emit signal for application developer
1111 if( !mSetSizeSignalV2.Empty() )
1113 Dali::Actor handle( this );
1114 mSetSizeSignalV2.Emit( handle, size );
1119 void Actor::SetWidth( float width )
1123 // mNode is being used in a separate thread; queue a message to set the value & base value
1124 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1128 void Actor::SetHeight( float height )
1132 // mNode is being used in a separate thread; queue a message to set the value & base value
1133 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1137 void Actor::SetDepth( float depth )
1141 // mNode is being used in a separate thread; queue a message to set the value & base value
1142 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1146 const Vector3& Actor::GetCurrentSize() const
1150 // mNode is being used in a separate thread; copy the value from the previous update
1151 return mNode->GetSize( mStage->GetEventBufferIndex() );
1154 return Vector3::ZERO;
1157 #ifdef DYNAMICS_SUPPORT
1159 //--------------- Dynamics ---------------
1161 void Actor::DisableDynamics()
1163 if( NULL != mDynamicsData )
1165 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1167 // ensure dynamics object are disconnected from scene
1168 DisconnectDynamics();
1170 // delete joint owned by this actor
1171 while( !mDynamicsData->joints.empty() )
1173 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1176 // delete other joints referencing this actor
1177 while( !mDynamicsData->referencedJoints.empty() )
1179 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1180 ActorPtr jointOwner( joint->GetActor( true ) );
1183 jointOwner->RemoveDynamicsJoint( joint );
1187 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1190 // delete the DynamicsBody object
1191 mDynamicsData->body.Reset();
1193 // Discard Dynamics data structure
1194 delete mDynamicsData;
1195 mDynamicsData = NULL;
1199 DynamicsBodyPtr Actor::GetDynamicsBody() const
1201 DynamicsBodyPtr body;
1203 if( NULL != mDynamicsData )
1205 body = mDynamicsData->body;
1211 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1213 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1215 if( NULL == mDynamicsData )
1217 mDynamicsData = new DynamicsData( this );
1220 if( !mDynamicsData->body )
1222 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1226 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1229 if( mParent == world->GetRootActor().Get() )
1231 mDynamicsData->body->Connect(*mStage);
1237 return mDynamicsData->body;
1240 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1242 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1243 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1246 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1248 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1249 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1251 DynamicsJointPtr joint;
1253 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1257 if( NULL != mDynamicsData )
1259 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1261 if( mDynamicsData->joints.end() != it )
1263 // use existing joint
1269 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1270 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1274 bodyA = EnableDynamics( new DynamicsBodyConfig );
1279 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1282 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1283 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1285 if( OnStage() && attachedActor->OnStage() )
1287 joint->Connect(*mStage);
1290 attachedActor->ReferenceJoint( joint );
1292 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1293 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1300 const int Actor::GetNumberOfJoints() const
1302 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1305 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1307 DynamicsJointPtr joint;
1309 if( NULL != mDynamicsData )
1311 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1313 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1315 for( int i = 0; i < index; ++i )
1327 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1329 DynamicsJointPtr joint;
1331 if( NULL != mDynamicsData )
1333 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1335 if( mDynamicsData->joints.end() != it )
1337 // use existing joint
1345 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1347 if( NULL != mDynamicsData )
1349 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1350 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1352 for( ; it != endIt; ++it )
1354 if( it->second == joint.Get() )
1356 ActorPtr attachedActor( it->first );
1358 if( OnStage() && attachedActor && attachedActor->OnStage() )
1360 joint->Disconnect(*mStage);
1365 attachedActor->ReleaseJoint( joint );
1366 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1367 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1370 mDynamicsData->joints.erase(it);
1377 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1379 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1381 if( NULL != mDynamicsData )
1383 mDynamicsData->referencedJoints.push_back(joint);
1387 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1389 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1391 if( NULL != mDynamicsData )
1393 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1395 if( it != mDynamicsData->referencedJoints.end() )
1397 mDynamicsData->referencedJoints.erase( it );
1402 void Actor::SetDynamicsRoot(bool flag)
1404 if( mIsDynamicsRoot != flag )
1406 mIsDynamicsRoot = flag;
1408 if( OnStage() && mChildren )
1410 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1411 ActorIter end = mChildren->end();
1412 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1414 Actor& child = GetImplementation(*iter);
1416 if( child.GetDynamicsBody() )
1418 if( mIsDynamicsRoot )
1420 child.ConnectDynamics();
1424 child.DisconnectDynamics();
1432 bool Actor::IsDynamicsRoot() const
1434 return mIsDynamicsRoot;
1437 void Actor::AttachedActorOnStage( Dali::Actor actor )
1439 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1443 ActorPtr attachedActor( &GetImplementation(actor) );
1445 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1446 if( NULL != mDynamicsData )
1448 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1449 if( mDynamicsData->joints.end() != it )
1451 DynamicsJointPtr joint( it->second );
1452 joint->Connect(*mStage);
1458 void Actor::AttachedActorOffStage( Dali::Actor actor )
1460 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1464 ActorPtr attachedActor( &GetImplementation(actor) );
1466 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1467 if( NULL != mDynamicsData )
1469 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1470 if( mDynamicsData->joints.end() != it )
1472 DynamicsJointPtr joint( it->second );
1473 joint->Disconnect(*mStage);
1479 void Actor::ConnectDynamics()
1481 if( NULL != mDynamicsData && mDynamicsData->body )
1483 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1485 mDynamicsData->body->Connect(*mStage);
1487 // Connect all joints where attachedActor is also on stage
1488 if( !mDynamicsData->joints.empty() )
1490 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1491 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1493 for( ; it != endIt; ++it )
1495 Actor* attachedActor( it->first );
1496 if( NULL != attachedActor && attachedActor->OnStage() )
1498 DynamicsJointPtr joint( it->second );
1500 joint->Connect(*mStage);
1508 void Actor::DisconnectDynamics()
1510 if( NULL != mDynamicsData && mDynamicsData->body )
1514 mDynamicsData->body->Disconnect(*mStage);
1516 // Disconnect all joints
1517 if( !mDynamicsData->joints.empty() )
1519 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1520 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1522 for( ; it != endIt; ++it )
1524 DynamicsJointPtr joint( it->second );
1526 joint->Disconnect(*mStage);
1533 #endif // DYNAMICS_SUPPORT
1535 void Actor::SetOverlay(bool enable)
1537 // Setting STENCIL will override OVERLAY
1538 if( DrawMode::STENCIL != mDrawMode )
1540 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1544 bool Actor::IsOverlay() const
1546 return ( DrawMode::OVERLAY == mDrawMode );
1549 void Actor::SetDrawMode( DrawMode::Type drawMode )
1551 // this flag is not animatable so keep the value
1552 mDrawMode = drawMode;
1555 // mNode is being used in a separate thread; queue a message to set the value
1556 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1560 DrawMode::Type Actor::GetDrawMode() const
1565 bool Actor::ScreenToLocal( float& localX,
1568 float screenY ) const
1570 // only valid when on-stage
1573 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1575 Vector2 converted( screenX, screenY );
1577 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1578 const int taskCount = taskList.GetTaskCount();
1579 for( int i = taskCount - 1; i >= 0; --i )
1581 Dali::RenderTask task = taskList.GetTask( i );
1582 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1584 // found a task where this conversion was ok so return
1592 bool Actor::ScreenToLocal( RenderTask& renderTask,
1596 float screenY ) const
1598 bool retval = false;
1599 // only valid when on-stage
1602 CameraActor* camera = renderTask.GetCameraActor();
1606 renderTask.GetViewport( viewport );
1608 // need to translate coordinates to render tasks coordinate space
1609 Vector2 converted( screenX, screenY );
1610 if( renderTask.TranslateCoordinates( converted ) )
1612 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1619 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1620 const Matrix& projectionMatrix,
1621 const Viewport& viewport,
1625 float screenY ) const
1627 // Early-out if mNode is NULL
1633 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1635 // Calculate the ModelView matrix
1636 Matrix modelView(false/*don't init*/);
1637 // need to use the components as world matrix is only updated for actors that need it
1638 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1639 Matrix::Multiply(modelView, modelView, viewMatrix);
1641 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1642 Matrix invertedMvp(false/*don't init*/);
1643 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1644 bool success = invertedMvp.Invert();
1646 // Convert to GL coordinates
1647 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1652 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1659 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1665 if (XyPlaneIntersect(nearPos, farPos, local))
1667 Vector3 size = GetCurrentSize();
1668 localX = local.x + size.x * 0.5f;
1669 localY = local.y + size.y * 0.5f;
1680 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1683 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1685 Mathematical Formulation
1687 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1689 ( p - c ) dot ( p - c ) = r^2
1691 Given a ray with a point of origin 'o', and a direction vector 'd':
1693 ray(t) = o + td, t >= 0
1695 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1697 (o + td - c ) dot ( o + td - c ) = r^2
1699 To solve for t we first expand the above into a more recognisable quadratic equation form
1701 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1710 B = 2( o - c ) dot d
1711 C = ( o - c ) dot ( o - c ) - r^2
1713 which can be solved using a standard quadratic formula.
1715 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1717 Practical Simplification
1719 In a renderer, we often differentiate between world space and object space. In the object space
1720 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1721 into object space, the mathematical solution presented above can be simplified significantly.
1723 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1727 and we can find the t at which the (transformed) ray intersects the sphere by
1729 ( o + td ) dot ( o + td ) = r^2
1731 According to the reasoning above, we expand the above quadratic equation into the general form
1735 which now has coefficients:
1742 // Early out if mNode is NULL
1748 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1750 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1751 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1752 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1753 rayOrigin.y - translation.y,
1754 rayOrigin.z - translation.z);
1756 // Compute the radius is not needed, square radius it's enough.
1757 const Vector3& size( mNode->GetSize( bufferIndex ) );
1759 // Scale the sphere.
1760 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1762 const float width = size.width * scale.width;
1763 const float height = size.height * scale.height;
1765 float squareSphereRadius = 0.5f * ( width * width + height * height );
1767 float a = rayDir.Dot( rayDir ); // a
1768 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1769 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1771 return ( b2*b2 - a*c ) >= 0.f;
1774 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1781 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1783 // Transforms the ray to the local reference system.
1785 // Calculate the inverse of Model matrix
1786 Matrix invModelMatrix(false/*don't init*/);
1787 // need to use the components as world matrix is only updated for actors that need it
1788 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1790 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1791 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1793 // Test with the actor's XY plane (Normal = 0 0 1 1).
1795 float a = -rayOriginLocal.z;
1796 float b = rayDirLocal.z;
1798 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1800 // Ray travels distance * rayDirLocal to intersect with plane.
1803 const Vector3& size = mNode->GetSize( bufferIndex );
1805 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1806 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1808 // Test with the actor's geometry.
1809 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1816 void Actor::SetLeaveRequired(bool required)
1818 mLeaveRequired = required;
1821 bool Actor::GetLeaveRequired() const
1823 return mLeaveRequired;
1826 void Actor::SetKeyboardFocusable( bool focusable )
1828 mKeyboardFocusable = focusable;
1831 bool Actor::IsKeyboardFocusable() const
1833 return mKeyboardFocusable;
1836 bool Actor::GetTouchRequired() const
1838 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1841 bool Actor::GetMouseWheelEventRequired() const
1843 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1846 bool Actor::IsHittable() const
1848 return IsSensitive() &&
1850 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1854 ActorGestureData& Actor::GetGestureData()
1856 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1857 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1858 if ( NULL == mGestureData )
1860 mGestureData = new ActorGestureData;
1862 return *mGestureData;
1865 bool Actor::IsGestureRequred( Gesture::Type type ) const
1867 return mGestureData && mGestureData->IsGestureRequred( type );
1870 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1872 bool consumed = false;
1874 if ( !mTouchedSignalV2.Empty() )
1876 Dali::Actor handle( this );
1877 consumed = mTouchedSignalV2.Emit( handle, event );
1882 // Notification for derived classes
1883 consumed = OnTouchEvent( event );
1889 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1891 bool consumed = false;
1893 if ( !mMouseWheelEventSignalV2.Empty() )
1895 Dali::Actor handle( this );
1896 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1901 // Notification for derived classes
1902 consumed = OnMouseWheelEvent(event);
1908 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1910 return mTouchedSignalV2;
1913 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1915 return mMouseWheelEventSignalV2;
1918 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1920 return mSetSizeSignalV2;
1923 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1925 return mOnStageSignalV2;
1928 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1930 return mOffStageSignalV2;
1933 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1935 bool connected( true );
1936 Actor* actor = dynamic_cast<Actor*>(object);
1938 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1940 actor->TouchedSignal().Connect( tracker, functor );
1942 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1944 actor->MouseWheelEventSignal().Connect( tracker, functor );
1946 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1948 actor->SetSizeSignal().Connect( tracker, functor );
1950 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1952 actor->OnStageSignal().Connect( tracker, functor );
1954 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1956 actor->OffStageSignal().Connect( tracker, functor );
1960 // signalName does not match any signal
1967 Actor::Actor( DerivedType derivedType )
1972 mParentOrigin( NULL ),
1973 mAnchorPoint( NULL ),
1974 #ifdef DYNAMICS_SUPPORT
1975 mDynamicsData( NULL ),
1977 mGestureData( NULL ),
1980 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1981 mIsRoot( ROOT_LAYER == derivedType ),
1982 mIsRenderable( RENDERABLE == derivedType ),
1983 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1984 mIsOnStage( false ),
1985 mIsDynamicsRoot(false),
1987 mLeaveRequired( false ),
1988 mKeyboardFocusable( false ),
1989 mDerivedRequiresTouch( false ),
1990 mDerivedRequiresMouseWheelEvent( false ),
1991 mOnStageSignalled( false ),
1992 mInheritRotation( true ),
1993 mInheritScale( true ),
1994 mDrawMode( DrawMode::NORMAL ),
1995 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1996 mColorMode( Node::DEFAULT_COLOR_MODE )
2000 void Actor::Initialize()
2002 mStage = Stage::GetCurrent();
2005 SceneGraph::Node* node = CreateNode();
2007 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
2008 mNode = node; // Keep raw-pointer to Node
2010 if(!mDefaultPropertyLookup)
2012 mDefaultPropertyLookup = new DefaultPropertyLookup();
2014 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
2016 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2027 // Remove mParent pointers from children even if we're destroying core,
2028 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2031 ActorConstIter endIter = mChildren->end();
2032 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2034 Actor& actor = GetImplementation( *iter );
2035 actor.SetParent( NULL );
2040 // Guard to allow handle destruction after Core has been destroyed
2041 if( Stage::IsInstalled() )
2045 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2046 mNode = NULL; // Node is about to be destroyed
2052 #ifdef DYNAMICS_SUPPORT
2054 delete mDynamicsData;
2057 // Cleanup optional gesture data
2058 delete mGestureData;
2060 // Cleanup optional parent origin and anchor
2061 delete mParentOrigin;
2062 delete mAnchorPoint;
2065 void Actor::ConnectToStage( Stage& stage, int index )
2067 // This container is used instead of walking the Actor hierachy.
2068 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2069 ActorContainer connectionList;
2071 // This stage is atomic i.e. not interrupted by user callbacks
2072 RecursiveConnectToStage( stage, connectionList, index );
2074 // Notify applications about the newly connected actors.
2075 const ActorIter endIter = connectionList.end();
2076 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2078 Actor& actor = GetImplementation(*iter);
2079 actor.NotifyStageConnection();
2083 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList, int index )
2085 DALI_ASSERT_ALWAYS( !OnStage() );
2089 ConnectToSceneGraph(index);
2091 // Notification for internal derived classes
2092 OnStageConnectionInternal();
2094 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2095 connectionList.push_back( Dali::Actor(this) );
2097 // Recursively connect children
2100 ActorConstIter endIter = mChildren->end();
2101 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2103 Actor& actor = GetImplementation( *iter );
2104 actor.RecursiveConnectToStage( stage, connectionList );
2110 * This method is called when the Actor is connected to the Stage.
2111 * The parent must have added its Node to the scene-graph.
2112 * The child must connect its Node to the parent's Node.
2113 * This is resursive; the child calls ConnectToStage() for its children.
2115 void Actor::ConnectToSceneGraph(int index)
2117 DALI_ASSERT_DEBUG( mNode != NULL);
2118 DALI_ASSERT_DEBUG( mParent != NULL);
2119 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2123 // Reparent Node in next Update
2124 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode, index );
2127 // Notify attachment
2130 mAttachment->Connect();
2133 #ifdef DYNAMICS_SUPPORT
2135 if( NULL != mDynamicsData )
2141 // Notification for ProxyObject::Observers
2145 void Actor::NotifyStageConnection()
2147 // Actors can be removed (in a callback), before the on-stage stage is reported.
2148 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2149 if ( OnStage() && !mOnStageSignalled )
2151 // Notification for external (CustomActor) derived classes
2152 OnStageConnectionExternal();
2154 if ( !mOnStageSignalV2.Empty() )
2156 Dali::Actor handle( this );
2157 mOnStageSignalV2.Emit( handle );
2160 // Guard against Remove during callbacks
2163 mOnStageSignalled = true; // signal required next time Actor is removed
2168 void Actor::DisconnectFromStage()
2170 // This container is used instead of walking the Actor hierachy.
2171 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2172 ActorContainer disconnectionList;
2174 // This stage is atomic i.e. not interrupted by user callbacks
2175 RecursiveDisconnectFromStage( disconnectionList );
2177 // Notify applications about the newly disconnected actors.
2178 const ActorIter endIter = disconnectionList.end();
2179 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2181 Actor& actor = GetImplementation(*iter);
2182 actor.NotifyStageDisconnection();
2186 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2188 DALI_ASSERT_ALWAYS( OnStage() );
2190 // Recursively disconnect children
2193 ActorConstIter endIter = mChildren->end();
2194 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2196 Actor& actor = GetImplementation( *iter );
2197 actor.RecursiveDisconnectFromStage( disconnectionList );
2201 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2202 disconnectionList.push_back( Dali::Actor(this) );
2204 // Notification for internal derived classes
2205 OnStageDisconnectionInternal();
2207 DisconnectFromSceneGraph();
2213 * This method is called by an actor or its parent, before a node removal message is sent.
2214 * This is recursive; the child calls DisconnectFromStage() for its children.
2216 void Actor::DisconnectFromSceneGraph()
2218 // Notification for ProxyObject::Observers
2219 OnSceneObjectRemove();
2221 // Notify attachment
2224 mAttachment->Disconnect();
2227 #ifdef DYNAMICS_SUPPORT
2229 if( NULL != mDynamicsData )
2231 DisconnectDynamics();
2236 void Actor::NotifyStageDisconnection()
2238 // Actors can be added (in a callback), before the off-stage state is reported.
2239 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2240 // only do this step if there is a stage, i.e. Core is not being shut down
2241 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2243 // Notification for external (CustomeActor) derived classes
2244 OnStageDisconnectionExternal();
2246 if( !mOffStageSignalV2.Empty() )
2248 Dali::Actor handle( this );
2249 mOffStageSignalV2.Emit( handle );
2252 // Guard against Add during callbacks
2255 mOnStageSignalled = false; // signal required next time Actor is added
2260 bool Actor::IsNodeConnected() const
2262 bool connected( false );
2267 if( mNode->IsRoot() || mNode->GetParent() )
2276 bool Actor::IsSceneObjectRemovable() const
2281 unsigned int Actor::GetDefaultPropertyCount() const
2283 return DEFAULT_PROPERTY_COUNT;
2286 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2288 indices.reserve( DEFAULT_PROPERTY_COUNT );
2290 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2292 indices.push_back( i );
2296 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2298 if( index < DEFAULT_PROPERTY_COUNT )
2300 return DEFAULT_PROPERTY_DETAILS[index].name;
2304 // index out of range..return empty string
2305 return String::EMPTY;
2309 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2311 Property::Index index = Property::INVALID_INDEX;
2313 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2315 // Look for name in default properties
2316 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2317 if ( mDefaultPropertyLookup->end() != result )
2319 index = result->second;
2325 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2327 if( index < DEFAULT_PROPERTY_COUNT )
2329 return DEFAULT_PROPERTY_DETAILS[index].writable;
2337 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2339 if( index < DEFAULT_PROPERTY_COUNT )
2341 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2349 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2351 if( index < DEFAULT_PROPERTY_COUNT )
2353 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2361 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2363 if( index < DEFAULT_PROPERTY_COUNT )
2365 return DEFAULT_PROPERTY_DETAILS[index].type;
2369 // index out of range...return Property::NONE
2370 return Property::NONE;
2374 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2378 case Dali::Actor::PARENT_ORIGIN:
2380 SetParentOrigin( property.Get<Vector3>() );
2384 case Dali::Actor::PARENT_ORIGIN_X:
2386 SetParentOriginX( property.Get<float>() );
2390 case Dali::Actor::PARENT_ORIGIN_Y:
2392 SetParentOriginY( property.Get<float>() );
2396 case Dali::Actor::PARENT_ORIGIN_Z:
2398 SetParentOriginZ( property.Get<float>() );
2402 case Dali::Actor::ANCHOR_POINT:
2404 SetAnchorPoint( property.Get<Vector3>() );
2408 case Dali::Actor::ANCHOR_POINT_X:
2410 SetAnchorPointX( property.Get<float>() );
2414 case Dali::Actor::ANCHOR_POINT_Y:
2416 SetAnchorPointY( property.Get<float>() );
2420 case Dali::Actor::ANCHOR_POINT_Z:
2422 SetAnchorPointZ( property.Get<float>() );
2426 case Dali::Actor::SIZE:
2428 SetSize( property.Get<Vector3>() );
2432 case Dali::Actor::SIZE_WIDTH:
2434 SetWidth( property.Get<float>() );
2438 case Dali::Actor::SIZE_HEIGHT:
2440 SetHeight( property.Get<float>() );
2444 case Dali::Actor::SIZE_DEPTH:
2446 SetDepth( property.Get<float>() );
2450 case Dali::Actor::POSITION:
2452 SetPosition( property.Get<Vector3>() );
2456 case Dali::Actor::POSITION_X:
2458 SetX( property.Get<float>() );
2462 case Dali::Actor::POSITION_Y:
2464 SetY( property.Get<float>() );
2468 case Dali::Actor::POSITION_Z:
2470 SetZ( property.Get<float>() );
2474 case Dali::Actor::ROTATION:
2476 SetRotation( property.Get<Quaternion>() );
2480 case Dali::Actor::SCALE:
2482 SetScale( property.Get<Vector3>() );
2486 case Dali::Actor::SCALE_X:
2488 SetScaleX( property.Get<float>() );
2492 case Dali::Actor::SCALE_Y:
2494 SetScaleY( property.Get<float>() );
2498 case Dali::Actor::SCALE_Z:
2500 SetScaleZ( property.Get<float>() );
2504 case Dali::Actor::VISIBLE:
2506 SetVisible( property.Get<bool>() );
2510 case Dali::Actor::COLOR:
2512 SetColor( property.Get<Vector4>() );
2516 case Dali::Actor::COLOR_RED:
2518 SetColorRed( property.Get<float>() );
2522 case Dali::Actor::COLOR_GREEN:
2524 SetColorGreen( property.Get<float>() );
2528 case Dali::Actor::COLOR_BLUE:
2530 SetColorBlue( property.Get<float>() );
2534 case Dali::Actor::COLOR_ALPHA:
2536 SetOpacity( property.Get<float>() );
2540 case Dali::Actor::NAME:
2542 SetName( property.Get<std::string>() );
2546 case Dali::Actor::SENSITIVE:
2548 SetSensitive( property.Get<bool>() );
2552 case Dali::Actor::LEAVE_REQUIRED:
2554 SetLeaveRequired( property.Get<bool>() );
2558 case Dali::Actor::INHERIT_ROTATION:
2560 SetInheritRotation( property.Get<bool>() );
2564 case Dali::Actor::INHERIT_SCALE:
2566 SetInheritScale( property.Get<bool>() );
2570 case Dali::Actor::COLOR_MODE:
2572 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2576 case Dali::Actor::POSITION_INHERITANCE:
2578 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2582 case Dali::Actor::DRAW_MODE:
2584 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2590 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2596 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2598 // TODO: This should be deprecated
2599 OnPropertySet(index, value);
2601 if(entry.IsAnimatable())
2603 // TODO: ADD MATRIX & MATRIX3 types
2605 switch ( entry.type )
2607 case Property::BOOLEAN:
2609 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2610 DALI_ASSERT_DEBUG( NULL != property );
2612 // property is being used in a separate thread; queue a message to set the property
2613 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2618 case Property::FLOAT:
2620 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2621 DALI_ASSERT_DEBUG( NULL != property );
2623 // property is being used in a separate thread; queue a message to set the property
2624 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2629 case Property::INTEGER:
2631 AnimatableProperty<int>* property = dynamic_cast< AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2632 DALI_ASSERT_DEBUG( NULL != property );
2634 // property is being used in a separate thread; queue a message to set the property
2635 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2640 case Property::VECTOR2:
2642 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2643 DALI_ASSERT_DEBUG( NULL != property );
2645 // property is being used in a separate thread; queue a message to set the property
2646 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2651 case Property::VECTOR3:
2653 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2654 DALI_ASSERT_DEBUG( NULL != property );
2656 // property is being used in a separate thread; queue a message to set the property
2657 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2662 case Property::VECTOR4:
2664 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2665 DALI_ASSERT_DEBUG( NULL != property );
2667 // property is being used in a separate thread; queue a message to set the property
2668 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2673 case Property::ROTATION:
2675 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2676 DALI_ASSERT_DEBUG( NULL != property );
2678 // property is being used in a separate thread; queue a message to set the property
2679 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2686 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2693 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2695 Property::Value value;
2699 case Dali::Actor::PARENT_ORIGIN:
2701 value = GetCurrentParentOrigin();
2705 case Dali::Actor::PARENT_ORIGIN_X:
2707 value = GetCurrentParentOrigin().x;
2711 case Dali::Actor::PARENT_ORIGIN_Y:
2713 value = GetCurrentParentOrigin().y;
2717 case Dali::Actor::PARENT_ORIGIN_Z:
2719 value = GetCurrentParentOrigin().z;
2723 case Dali::Actor::ANCHOR_POINT:
2725 value = GetCurrentAnchorPoint();
2729 case Dali::Actor::ANCHOR_POINT_X:
2731 value = GetCurrentAnchorPoint().x;
2735 case Dali::Actor::ANCHOR_POINT_Y:
2737 value = GetCurrentAnchorPoint().y;
2741 case Dali::Actor::ANCHOR_POINT_Z:
2743 value = GetCurrentAnchorPoint().z;
2747 case Dali::Actor::SIZE:
2749 value = GetCurrentSize();
2753 case Dali::Actor::SIZE_WIDTH:
2755 value = GetCurrentSize().width;
2759 case Dali::Actor::SIZE_HEIGHT:
2761 value = GetCurrentSize().height;
2765 case Dali::Actor::SIZE_DEPTH:
2767 value = GetCurrentSize().depth;
2771 case Dali::Actor::POSITION:
2773 value = GetCurrentPosition();
2777 case Dali::Actor::POSITION_X:
2779 value = GetCurrentPosition().x;
2783 case Dali::Actor::POSITION_Y:
2785 value = GetCurrentPosition().y;
2789 case Dali::Actor::POSITION_Z:
2791 value = GetCurrentPosition().z;
2795 case Dali::Actor::WORLD_POSITION:
2797 value = GetCurrentWorldPosition();
2801 case Dali::Actor::WORLD_POSITION_X:
2803 value = GetCurrentWorldPosition().x;
2807 case Dali::Actor::WORLD_POSITION_Y:
2809 value = GetCurrentWorldPosition().y;
2813 case Dali::Actor::WORLD_POSITION_Z:
2815 value = GetCurrentWorldPosition().z;
2819 case Dali::Actor::ROTATION:
2821 value = GetCurrentRotation();
2825 case Dali::Actor::WORLD_ROTATION:
2827 value = GetCurrentWorldRotation();
2831 case Dali::Actor::SCALE:
2833 value = GetCurrentScale();
2837 case Dali::Actor::SCALE_X:
2839 value = GetCurrentScale().x;
2843 case Dali::Actor::SCALE_Y:
2845 value = GetCurrentScale().y;
2849 case Dali::Actor::SCALE_Z:
2851 value = GetCurrentScale().z;
2855 case Dali::Actor::WORLD_SCALE:
2857 value = GetCurrentWorldScale();
2861 case Dali::Actor::VISIBLE:
2863 value = IsVisible();
2867 case Dali::Actor::COLOR:
2869 value = GetCurrentColor();
2873 case Dali::Actor::COLOR_RED:
2875 value = GetCurrentColor().r;
2879 case Dali::Actor::COLOR_GREEN:
2881 value = GetCurrentColor().g;
2885 case Dali::Actor::COLOR_BLUE:
2887 value = GetCurrentColor().b;
2891 case Dali::Actor::COLOR_ALPHA:
2893 value = GetCurrentColor().a;
2897 case Dali::Actor::WORLD_COLOR:
2899 value = GetCurrentWorldColor();
2903 case Dali::Actor::WORLD_MATRIX:
2905 value = GetCurrentWorldMatrix();
2909 case Dali::Actor::NAME:
2915 case Dali::Actor::SENSITIVE:
2917 value = IsSensitive();
2921 case Dali::Actor::LEAVE_REQUIRED:
2923 value = GetLeaveRequired();
2927 case Dali::Actor::INHERIT_ROTATION:
2929 value = IsRotationInherited();
2933 case Dali::Actor::INHERIT_SCALE:
2935 value = IsScaleInherited();
2939 case Dali::Actor::COLOR_MODE:
2941 value = Scripting::GetColorMode( GetColorMode() );
2945 case Dali::Actor::POSITION_INHERITANCE:
2947 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2951 case Dali::Actor::DRAW_MODE:
2953 value = Scripting::GetDrawMode( GetDrawMode() );
2959 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2967 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2971 // mNode is being used in a separate thread; queue a message to add the property
2972 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
2976 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2978 // This method should only return an object connected to the scene-graph
2979 return OnStage() ? mNode : NULL;
2982 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2984 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2986 const PropertyBase* property( NULL );
2988 // This method should only return a property of an object connected to the scene-graph
2994 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
2996 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
2998 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
3000 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
3002 else if( NULL != mNode )
3006 case Dali::Actor::SIZE:
3007 property = &mNode->mSize;
3010 case Dali::Actor::SIZE_WIDTH:
3011 property = &mNode->mSize;
3014 case Dali::Actor::SIZE_HEIGHT:
3015 property = &mNode->mSize;
3018 case Dali::Actor::SIZE_DEPTH:
3019 property = &mNode->mSize;
3022 case Dali::Actor::POSITION:
3023 property = &mNode->mPosition;
3026 case Dali::Actor::POSITION_X:
3027 property = &mNode->mPosition;
3030 case Dali::Actor::POSITION_Y:
3031 property = &mNode->mPosition;
3034 case Dali::Actor::POSITION_Z:
3035 property = &mNode->mPosition;
3038 case Dali::Actor::ROTATION:
3039 property = &mNode->mRotation;
3042 case Dali::Actor::SCALE:
3043 property = &mNode->mScale;
3046 case Dali::Actor::SCALE_X:
3047 property = &mNode->mScale;
3050 case Dali::Actor::SCALE_Y:
3051 property = &mNode->mScale;
3054 case Dali::Actor::SCALE_Z:
3055 property = &mNode->mScale;
3058 case Dali::Actor::VISIBLE:
3059 property = &mNode->mVisible;
3062 case Dali::Actor::COLOR:
3063 property = &mNode->mColor;
3066 case Dali::Actor::COLOR_RED:
3067 property = &mNode->mColor;
3070 case Dali::Actor::COLOR_GREEN:
3071 property = &mNode->mColor;
3074 case Dali::Actor::COLOR_BLUE:
3075 property = &mNode->mColor;
3078 case Dali::Actor::COLOR_ALPHA:
3079 property = &mNode->mColor;
3090 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3092 const PropertyInputImpl* property( NULL );
3094 // This method should only return a property of an object connected to the scene-graph
3100 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3102 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3104 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3106 property = entry->second.GetSceneGraphProperty();
3108 else if( NULL != mNode )
3112 case Dali::Actor::PARENT_ORIGIN:
3113 property = &mNode->mParentOrigin;
3116 case Dali::Actor::PARENT_ORIGIN_X:
3117 property = &mNode->mParentOrigin;
3120 case Dali::Actor::PARENT_ORIGIN_Y:
3121 property = &mNode->mParentOrigin;
3124 case Dali::Actor::PARENT_ORIGIN_Z:
3125 property = &mNode->mParentOrigin;
3128 case Dali::Actor::ANCHOR_POINT:
3129 property = &mNode->mAnchorPoint;
3132 case Dali::Actor::ANCHOR_POINT_X:
3133 property = &mNode->mAnchorPoint;
3136 case Dali::Actor::ANCHOR_POINT_Y:
3137 property = &mNode->mAnchorPoint;
3140 case Dali::Actor::ANCHOR_POINT_Z:
3141 property = &mNode->mAnchorPoint;
3144 case Dali::Actor::SIZE:
3145 property = &mNode->mSize;
3148 case Dali::Actor::SIZE_WIDTH:
3149 property = &mNode->mSize;
3152 case Dali::Actor::SIZE_HEIGHT:
3153 property = &mNode->mSize;
3156 case Dali::Actor::SIZE_DEPTH:
3157 property = &mNode->mSize;
3160 case Dali::Actor::POSITION:
3161 property = &mNode->mPosition;
3164 case Dali::Actor::POSITION_X:
3165 property = &mNode->mPosition;
3168 case Dali::Actor::POSITION_Y:
3169 property = &mNode->mPosition;
3172 case Dali::Actor::POSITION_Z:
3173 property = &mNode->mPosition;
3176 case Dali::Actor::WORLD_POSITION:
3177 property = &mNode->mWorldPosition;
3180 case Dali::Actor::WORLD_POSITION_X:
3181 property = &mNode->mWorldPosition;
3184 case Dali::Actor::WORLD_POSITION_Y:
3185 property = &mNode->mWorldPosition;
3188 case Dali::Actor::WORLD_POSITION_Z:
3189 property = &mNode->mWorldPosition;
3192 case Dali::Actor::ROTATION:
3193 property = &mNode->mRotation;
3196 case Dali::Actor::WORLD_ROTATION:
3197 property = &mNode->mWorldRotation;
3200 case Dali::Actor::SCALE:
3201 property = &mNode->mScale;
3204 case Dali::Actor::SCALE_X:
3205 property = &mNode->mScale;
3208 case Dali::Actor::SCALE_Y:
3209 property = &mNode->mScale;
3212 case Dali::Actor::SCALE_Z:
3213 property = &mNode->mScale;
3216 case Dali::Actor::WORLD_SCALE:
3217 property = &mNode->mWorldScale;
3220 case Dali::Actor::VISIBLE:
3221 property = &mNode->mVisible;
3224 case Dali::Actor::COLOR:
3225 property = &mNode->mColor;
3228 case Dali::Actor::COLOR_RED:
3229 property = &mNode->mColor;
3232 case Dali::Actor::COLOR_GREEN:
3233 property = &mNode->mColor;
3236 case Dali::Actor::COLOR_BLUE:
3237 property = &mNode->mColor;
3240 case Dali::Actor::COLOR_ALPHA:
3241 property = &mNode->mColor;
3244 case Dali::Actor::WORLD_COLOR:
3245 property = &mNode->mWorldColor;
3248 case Dali::Actor::WORLD_MATRIX:
3249 property = &mNode->mWorldMatrix;
3260 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3262 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3266 case Dali::Actor::PARENT_ORIGIN_X:
3267 case Dali::Actor::ANCHOR_POINT_X:
3268 case Dali::Actor::SIZE_WIDTH:
3269 case Dali::Actor::POSITION_X:
3270 case Dali::Actor::SCALE_X:
3271 case Dali::Actor::COLOR_RED:
3272 case Dali::Actor::WORLD_POSITION_X:
3278 case Dali::Actor::PARENT_ORIGIN_Y:
3279 case Dali::Actor::ANCHOR_POINT_Y:
3280 case Dali::Actor::SIZE_HEIGHT:
3281 case Dali::Actor::POSITION_Y:
3282 case Dali::Actor::SCALE_Y:
3283 case Dali::Actor::COLOR_GREEN:
3284 case Dali::Actor::WORLD_POSITION_Y:
3290 case Dali::Actor::PARENT_ORIGIN_Z:
3291 case Dali::Actor::ANCHOR_POINT_Z:
3292 case Dali::Actor::SIZE_DEPTH:
3293 case Dali::Actor::POSITION_Z:
3294 case Dali::Actor::SCALE_Z:
3295 case Dali::Actor::COLOR_BLUE:
3296 case Dali::Actor::WORLD_POSITION_Z:
3302 case Dali::Actor::COLOR_ALPHA:
3315 return componentIndex;
3318 void Actor::SetParent(Actor* parent, int index)
3322 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3326 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3329 StagePtr stage = parent->mStage;
3331 // Instruct each actor to create a corresponding node in the scene graph
3332 ConnectToStage(*stage, index);
3335 else // parent being set to NULL
3337 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3341 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3344 DALI_ASSERT_ALWAYS(mNode != NULL);
3348 // Disconnect the Node & its children from the scene-graph.
3349 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3352 // Instruct each actor to discard pointers to the scene-graph
3353 DisconnectFromStage();
3358 SceneGraph::Node* Actor::CreateNode() const
3363 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3366 Actor* actor = dynamic_cast<Actor*>(object);
3370 if(Dali::Actor::ACTION_SHOW == actionName)
3372 actor->SetVisible(true);
3375 else if(Dali::Actor::ACTION_HIDE == actionName)
3377 actor->SetVisible(false);
3385 } // namespace Internal