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/event/effects/shader-effect-impl.h>
45 #include <dali/internal/update/common/animatable-property.h>
46 #include <dali/internal/update/common/property-owner-messages.h>
47 #include <dali/internal/update/nodes/node-messages.h>
48 #include <dali/internal/update/nodes/node-declarations.h>
49 #include <dali/internal/update/animation/scene-graph-constraint.h>
50 #include <dali/internal/event/events/actor-gesture-data.h>
51 #include <dali/internal/common/message.h>
52 #include <dali/integration-api/debug.h>
54 #ifdef DYNAMICS_SUPPORT
55 #include <dali/internal/event/dynamics/dynamics-body-config-impl.h>
56 #include <dali/internal/event/dynamics/dynamics-body-impl.h>
57 #include <dali/internal/event/dynamics/dynamics-joint-impl.h>
58 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
61 using Dali::Internal::SceneGraph::Node;
62 using Dali::Internal::SceneGraph::AnimatableProperty;
63 using Dali::Internal::SceneGraph::PropertyBase;
70 const Property::Index Actor::PARENT_ORIGIN = 0;
71 const Property::Index Actor::PARENT_ORIGIN_X = 1;
72 const Property::Index Actor::PARENT_ORIGIN_Y = 2;
73 const Property::Index Actor::PARENT_ORIGIN_Z = 3;
74 const Property::Index Actor::ANCHOR_POINT = 4;
75 const Property::Index Actor::ANCHOR_POINT_X = 5;
76 const Property::Index Actor::ANCHOR_POINT_Y = 6;
77 const Property::Index Actor::ANCHOR_POINT_Z = 7;
78 const Property::Index Actor::SIZE = 8;
79 const Property::Index Actor::SIZE_WIDTH = 9;
80 const Property::Index Actor::SIZE_HEIGHT = 10;
81 const Property::Index Actor::SIZE_DEPTH = 11;
82 const Property::Index Actor::POSITION = 12;
83 const Property::Index Actor::POSITION_X = 13;
84 const Property::Index Actor::POSITION_Y = 14;
85 const Property::Index Actor::POSITION_Z = 15;
86 const Property::Index Actor::WORLD_POSITION = 16;
87 const Property::Index Actor::WORLD_POSITION_X = 17;
88 const Property::Index Actor::WORLD_POSITION_Y = 18;
89 const Property::Index Actor::WORLD_POSITION_Z = 19;
90 const Property::Index Actor::ROTATION = 20;
91 const Property::Index Actor::WORLD_ROTATION = 21;
92 const Property::Index Actor::SCALE = 22;
93 const Property::Index Actor::SCALE_X = 23;
94 const Property::Index Actor::SCALE_Y = 24;
95 const Property::Index Actor::SCALE_Z = 25;
96 const Property::Index Actor::WORLD_SCALE = 26;
97 const Property::Index Actor::VISIBLE = 27;
98 const Property::Index Actor::COLOR = 28;
99 const Property::Index Actor::COLOR_RED = 29;
100 const Property::Index Actor::COLOR_GREEN = 30;
101 const Property::Index Actor::COLOR_BLUE = 31;
102 const Property::Index Actor::COLOR_ALPHA = 32;
103 const Property::Index Actor::WORLD_COLOR = 33;
104 const Property::Index Actor::WORLD_MATRIX = 34;
105 const Property::Index Actor::NAME = 35;
106 const Property::Index Actor::SENSITIVE = 36;
107 const Property::Index Actor::LEAVE_REQUIRED = 37;
108 const Property::Index Actor::INHERIT_ROTATION = 38;
109 const Property::Index Actor::INHERIT_SCALE = 39;
110 const Property::Index Actor::COLOR_MODE = 40;
111 const Property::Index Actor::POSITION_INHERITANCE = 41;
112 const Property::Index Actor::DRAW_MODE = 42;
114 namespace // unnamed namespace
118 * We want to discourage the use of property strings (minimize string comparisons),
119 * particularly for the default properties.
121 const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
123 // Name Type writable animatable constraint-input
124 { "parent-origin", Property::VECTOR3, true, false, true }, // PARENT_ORIGIN
125 { "parent-origin-x", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_X
126 { "parent-origin-y", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Y
127 { "parent-origin-z", Property::FLOAT, true, false, true }, // PARENT_ORIGIN_Z
128 { "anchor-point", Property::VECTOR3, true, false, true }, // ANCHOR_POINT
129 { "anchor-point-x", Property::FLOAT, true, false, true }, // ANCHOR_POINT_X
130 { "anchor-point-y", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Y
131 { "anchor-point-z", Property::FLOAT, true, false, true }, // ANCHOR_POINT_Z
132 { "size", Property::VECTOR3, true, true, true }, // SIZE
133 { "size-width", Property::FLOAT, true, true, true }, // SIZE_WIDTH
134 { "size-height", Property::FLOAT, true, true, true }, // SIZE_HEIGHT
135 { "size-depth", Property::FLOAT, true, true, true }, // SIZE_DEPTH
136 { "position", Property::VECTOR3, true, true, true }, // POSITION
137 { "position-x", Property::FLOAT, true, true, true }, // POSITION_X
138 { "position-y", Property::FLOAT, true, true, true }, // POSITION_Y
139 { "position-z", Property::FLOAT, true, true, true }, // POSITION_Z
140 { "world-position", Property::VECTOR3, false, false, true }, // WORLD_POSITION
141 { "world-position-x", Property::FLOAT, false, false, true }, // WORLD_POSITION_X
142 { "world-position-y", Property::FLOAT, false, false, true }, // WORLD_POSITION_Y
143 { "world-position-z", Property::FLOAT, false, false, true }, // WORLD_POSITION_Z
144 { "rotation", Property::ROTATION, true, true, true }, // ROTATION
145 { "world-rotation", Property::ROTATION, false, false, true }, // WORLD_ROTATION
146 { "scale", Property::VECTOR3, true, true, true }, // SCALE
147 { "scale-x", Property::FLOAT, true, true, true }, // SCALE_X
148 { "scale-y", Property::FLOAT, true, true, true }, // SCALE_Y
149 { "scale-z", Property::FLOAT, true, true, true }, // SCALE_Z
150 { "world-scale", Property::VECTOR3, false, false, true }, // WORLD_SCALE
151 { "visible", Property::BOOLEAN, true, true, true }, // VISIBLE
152 { "color", Property::VECTOR4, true, true, true }, // COLOR
153 { "color-red", Property::FLOAT, true, true, true }, // COLOR_RED
154 { "color-green", Property::FLOAT, true, true, true }, // COLOR_GREEN
155 { "color-blue", Property::FLOAT, true, true, true }, // COLOR_BLUE
156 { "color-alpha", Property::FLOAT, true, true, true }, // COLOR_ALPHA
157 { "world-color", Property::VECTOR4, false, false, true }, // WORLD_COLOR
158 { "world-matrix", Property::MATRIX, false, false, true }, // WORLD_MATRIX
159 { "name", Property::STRING, true, false, false }, // NAME
160 { "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
161 { "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
162 { "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
163 { "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
164 { "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
165 { "position-inheritance", Property::STRING, true, false, false }, // POSITION_INHERITANCE
166 { "draw-mode", Property::STRING, true, false, false }, // DRAW_MODE
168 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
170 } // unnamed namespace
175 unsigned int Actor::mActorCounter = 0;
176 ActorContainer Actor::mNullChildren;
178 #ifdef DYNAMICS_SUPPORT
180 // Encapsulate actor related dynamics data
183 DynamicsData( Actor* slotOwner )
184 : slotDelegate( slotOwner )
188 typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
189 typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
191 DynamicsBodyPtr body;
192 JointContainer joints;
193 ReferencedJointContainer referencedJoints;
195 SlotDelegate< Actor > slotDelegate;
198 #endif // DYNAMICS_SUPPORT
203 using namespace Dali;
205 BaseHandle CreateActor()
207 return Dali::Actor::New();
210 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
212 SignalConnectorType signalConnector1(mType, Dali::Actor::SIGNAL_TOUCHED, &Actor::DoConnectSignal);
213 SignalConnectorType signalConnector2(mType, Dali::Actor::SIGNAL_SET_SIZE, &Actor::DoConnectSignal);
214 SignalConnectorType signalConnector3(mType, Dali::Actor::SIGNAL_ON_STAGE, &Actor::DoConnectSignal);
215 SignalConnectorType signalConnector4(mType, Dali::Actor::SIGNAL_OFF_STAGE, &Actor::DoConnectSignal);
217 TypeAction a1(mType, Dali::Actor::ACTION_SHOW, &Actor::DoAction);
218 TypeAction a2(mType, Dali::Actor::ACTION_HIDE, &Actor::DoAction);
222 Actor::DefaultPropertyLookup* Actor::mDefaultPropertyLookup = NULL;
224 ActorPtr Actor::New()
226 ActorPtr actor( new Actor( BASIC ) );
228 // Second-phase construction
234 const std::string& Actor::GetName() const
239 void Actor::SetName(const std::string& name)
245 // ATTENTION: string for debug purposes is not thread safe.
246 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( mNode ), name );
250 unsigned int Actor::GetId() const
255 void Actor::Attach( ActorAttachment& attachment )
257 DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" );
261 attachment.Connect();
264 mAttachment = ActorAttachmentPtr(&attachment);
267 ActorAttachmentPtr Actor::GetAttachment()
272 bool Actor::OnStage() const
277 Dali::Layer Actor::GetLayer()
281 // Short-circuit for Layer derived actors
284 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
287 // Find the immediate Layer parent
288 for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
290 if( parent->IsLayer() )
292 layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
299 void Actor::Add(Actor& child)
301 DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
302 DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
306 mChildren = new ActorContainer;
309 Actor* const oldParent( child.mParent );
311 // child might already be ours
312 if( this != oldParent )
314 // if we already have parent, unparent us first
317 oldParent->Remove( child ); // This causes OnChildRemove callback
320 // Guard against Add() during previous OnChildRemove callback
321 if ( !child.mParent )
323 // Do this first, since user callbacks from within SetParent() may need to remove child
324 mChildren->push_back(Dali::Actor(&child));
326 // SetParent asserts that child can be added
327 child.SetParent(this);
329 // Notification for derived classes
335 void Actor::Remove(Actor& child)
337 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
347 // Find the child in mChildren, and unparent it
348 ActorIter end = mChildren->end();
349 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
351 Actor& actor = GetImplementation(*iter);
353 if( &actor == &child )
355 // Keep handle for OnChildRemove notification
356 removed = Dali::Actor( &actor );
358 // Do this first, since user callbacks from within SetParent() may need to add the child
359 mChildren->erase(iter);
361 DALI_ASSERT_DEBUG( actor.GetParent() == this );
362 actor.SetParent( NULL );
370 // Notification for derived classes
371 OnChildRemove( GetImplementation(removed) );
375 void Actor::Unparent()
379 mParent->Remove( *this );
383 unsigned int Actor::GetChildCount() const
385 return ( NULL != mChildren ) ? mChildren->size() : 0;
388 Dali::Actor Actor::GetChildAt(unsigned int index) const
390 DALI_ASSERT_ALWAYS( index < GetChildCount() );
392 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
395 ActorContainer Actor::GetChildren()
397 if( NULL != mChildren )
402 // return copy of mNullChildren
403 return mNullChildren;
406 const ActorContainer& Actor::GetChildren() const
408 if( NULL != mChildren )
413 // return const reference to mNullChildren
414 return mNullChildren;
417 ActorPtr Actor::FindChildByName(const std::string& actorName)
420 if (actorName == mName)
426 ActorIter end = mChildren->end();
427 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
429 child = GetImplementation(*iter).FindChildByName(actorName);
440 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
442 Dali::Actor child = DoGetChildByAlias(actorAlias);
444 // If not found then search by name.
447 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
450 child = Dali::Actor(child_ptr.Get());
457 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
459 Dali::Actor child = GetChildByAlias(actorAlias);
461 if (!child && mChildren )
463 ActorIter end = mChildren->end();
464 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
466 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
478 ActorPtr Actor::FindChildById(const unsigned int id)
487 ActorIter end = mChildren->end();
488 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
490 child = GetImplementation(*iter).FindChildById(id);
501 void Actor::SetParentOrigin( const Vector3& origin )
505 // mNode is being used in a separate thread; queue a message to set the value & base value
506 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
509 // Cache for event-thread access
512 // not allocated, check if different from default
513 if( ParentOrigin::DEFAULT != origin )
515 mParentOrigin = new Vector3( origin );
520 // check if different from current costs more than just set
521 *mParentOrigin = origin;
525 void Actor::SetParentOriginX( float x )
527 const Vector3& current = GetCurrentParentOrigin();
529 SetParentOrigin( Vector3( x, current.y, current.z ) );
532 void Actor::SetParentOriginY( float y )
534 const Vector3& current = GetCurrentParentOrigin();
536 SetParentOrigin( Vector3( current.x, y, current.z ) );
539 void Actor::SetParentOriginZ( float z )
541 const Vector3& current = GetCurrentParentOrigin();
543 SetParentOrigin( Vector3( current.x, current.y, z ) );
546 const Vector3& Actor::GetCurrentParentOrigin() const
548 // Cached for event-thread access
549 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
552 void Actor::SetAnchorPoint(const Vector3& anchor)
556 // mNode is being used in a separate thread; queue a message to set the value & base value
557 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
560 // Cache for event-thread access
563 // not allocated, check if different from default
564 if( AnchorPoint::DEFAULT != anchor )
566 mAnchorPoint = new Vector3( anchor );
571 // check if different from current costs more than just set
572 *mAnchorPoint = anchor;
576 void Actor::SetAnchorPointX( float x )
578 const Vector3& current = GetCurrentAnchorPoint();
580 SetAnchorPoint( Vector3( x, current.y, current.z ) );
583 void Actor::SetAnchorPointY( float y )
585 const Vector3& current = GetCurrentAnchorPoint();
587 SetAnchorPoint( Vector3( current.x, y, current.z ) );
590 void Actor::SetAnchorPointZ( float z )
592 const Vector3& current = GetCurrentAnchorPoint();
594 SetAnchorPoint( Vector3( current.x, current.y, z ) );
597 const Vector3& Actor::GetCurrentAnchorPoint() const
599 // Cached for event-thread access
600 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
603 void Actor::SetPosition(float x, float y)
605 SetPosition(Vector3(x, y, 0.0f));
608 void Actor::SetPosition(float x, float y, float z)
610 SetPosition(Vector3(x, y, z));
613 void Actor::SetPosition(const Vector3& position)
617 // mNode is being used in a separate thread; queue a message to set the value & base value
618 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
622 void Actor::SetX(float x)
626 // mNode is being used in a separate thread; queue a message to set the value & base value
627 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
631 void Actor::SetY(float y)
635 // mNode is being used in a separate thread; queue a message to set the value & base value
636 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
640 void Actor::SetZ(float z)
644 // mNode is being used in a separate thread; queue a message to set the value & base value
645 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
649 void Actor::MoveBy(const Vector3& distance)
653 // mNode is being used in a separate thread; queue a message to set the value & base value
654 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
658 const Vector3& Actor::GetCurrentPosition() const
662 // mNode is being used in a separate thread; copy the value from the previous update
663 return mNode->GetPosition(mStage->GetEventBufferIndex());
666 return Vector3::ZERO;
669 const Vector3& Actor::GetCurrentWorldPosition() const
673 // mNode is being used in a separate thread; copy the value from the previous update
674 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
677 return Vector3::ZERO;
680 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
682 // this flag is not animatable so keep the value
683 mPositionInheritanceMode = mode;
686 // mNode is being used in a separate thread; queue a message to set the value
687 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
691 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
693 // Cached for event-thread access
694 return mPositionInheritanceMode;
697 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
699 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
700 normalizedAxis.Normalize();
702 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
704 SetRotation(rotation);
707 void Actor::SetRotation(const Quaternion& rotation)
711 // mNode is being used in a separate thread; queue a message to set the value & base value
712 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
716 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
720 // mNode is being used in a separate thread; queue a message to set the value & base value
721 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
725 void Actor::RotateBy(const Quaternion& relativeRotation)
729 // mNode is being used in a separate thread; queue a message to set the value & base value
730 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
734 const Quaternion& Actor::GetCurrentRotation() const
738 // mNode is being used in a separate thread; copy the value from the previous update
739 return mNode->GetRotation(mStage->GetEventBufferIndex());
742 return Quaternion::IDENTITY;
745 const Quaternion& Actor::GetCurrentWorldRotation() const
749 // mNode is being used in a separate thread; copy the value from the previous update
750 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
753 return Quaternion::IDENTITY;
756 void Actor::SetScale(float scale)
758 SetScale(Vector3(scale, scale, scale));
761 void Actor::SetScale(float x, float y, float z)
763 SetScale(Vector3(x, y, z));
766 void Actor::SetScale(const Vector3& scale)
770 // mNode is being used in a separate thread; queue a message to set the value & base value
771 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
775 void Actor::SetScaleX( float x )
779 // mNode is being used in a separate thread; queue a message to set the value & base value
780 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
784 void Actor::SetScaleY( float y )
788 // mNode is being used in a separate thread; queue a message to set the value & base value
789 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
793 void Actor::SetScaleZ( float z )
797 // mNode is being used in a separate thread; queue a message to set the value & base value
798 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
802 void Actor::SetInitialVolume(const Vector3& volume)
806 // mNode is being used in a separate thread; queue a message to set the value
807 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
811 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
815 // mNode is being used in a separate thread; queue a message to set the value
816 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
820 bool Actor::GetTransmitGeometryScaling() const
824 // mNode is being used in a separate thread; copy the value from the previous update
825 return mNode->GetTransmitGeometryScaling();
831 void Actor::ScaleBy(const Vector3& relativeScale)
835 // mNode is being used in a separate thread; queue a message to set the value & base value
836 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
840 const Vector3& Actor::GetCurrentScale() const
844 // mNode is being used in a separate thread; copy the value from the previous update
845 return mNode->GetScale(mStage->GetEventBufferIndex());
851 const Vector3& Actor::GetCurrentWorldScale() const
855 // mNode is being used in a separate thread; copy the value from the previous update
856 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
862 void Actor::SetInheritScale( bool inherit )
864 // non animateable so keep local copy
865 mInheritScale = inherit;
868 // mNode is being used in a separate thread; queue a message to set the value
869 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
873 bool Actor::IsScaleInherited() const
875 return mInheritScale;
878 Matrix Actor::GetCurrentWorldMatrix() const
882 // World matrix is no longer updated unless there is something observing the node.
883 // Need to calculate it from node's world position, rotation and scale:
884 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
885 Matrix worldMatrix(false);
886 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
887 mNode->GetWorldRotation( updateBufferIndex ),
888 mNode->GetWorldPosition( updateBufferIndex ) );
892 return Matrix::IDENTITY;
895 void Actor::SetVisible(bool visible)
899 // mNode is being used in a separate thread; queue a message to set the value & base value
900 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
904 bool Actor::IsVisible() const
908 // mNode is being used in a separate thread; copy the value from the previous update
909 return mNode->IsVisible( mStage->GetEventBufferIndex() );
915 void Actor::SetOpacity(float opacity)
919 // mNode is being used in a separate thread; queue a message to set the value & base value
920 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
924 void Actor::OpacityBy(float relativeOpacity)
928 // mNode is being used in a separate thread; queue a message to set the value & base value
929 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
933 float Actor::GetCurrentOpacity() const
937 // mNode is being used in a separate thread; copy the value from the previous update
938 return mNode->GetOpacity(mStage->GetEventBufferIndex());
944 const Vector4& Actor::GetCurrentWorldColor() const
948 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
954 void Actor::SetColor(const Vector4& color)
958 // mNode is being used in a separate thread; queue a message to set the value & base value
959 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
963 void Actor::SetColorRed( float red )
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>::BakeX, red );
972 void Actor::SetColorGreen( float green )
976 // mNode is being used in a separate thread; queue a message to set the value & base value
977 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
981 void Actor::SetColorBlue( float blue )
985 // mNode is being used in a separate thread; queue a message to set the value & base value
986 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
990 void Actor::ColorBy(const Vector4& relativeColor)
994 // mNode is being used in a separate thread; queue a message to set the value & base value
995 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
999 const Vector4& Actor::GetCurrentColor() const
1003 // mNode is being used in a separate thread; copy the value from the previous update
1004 return mNode->GetColor(mStage->GetEventBufferIndex());
1007 return Color::WHITE;
1010 void Actor::SetInheritRotation(bool inherit)
1012 // non animateable so keep local copy
1013 mInheritRotation = inherit;
1016 // mNode is being used in a separate thread; queue a message to set the value
1017 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1021 bool Actor::IsRotationInherited() const
1023 return mInheritRotation;
1026 void Actor::SetColorMode(ColorMode colorMode)
1028 // non animateable so keep local copy
1029 mColorMode = colorMode;
1032 // mNode is being used in a separate thread; queue a message to set the value
1033 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1037 ColorMode Actor::GetColorMode() const
1039 // we have cached copy
1043 void Actor::SetSize(float width, float height)
1045 SetSize( Vector2( width, height ) );
1048 void Actor::SetSize(float width, float height, float depth)
1050 SetSize( Vector3( width, height, depth ) );
1053 void Actor::SetSize(const Vector2& size)
1055 Vector3 volume( size );
1056 volume.z = std::min( size.width, size.height );
1060 void Actor::SetSize(const Vector3& size)
1064 // mNode is being used in a separate thread; queue a message to set the value & base value
1065 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1067 // Notification for derived classes
1070 // Emit signal for application developer
1072 if( !mSetSizeSignalV2.Empty() )
1074 Dali::Actor handle( this );
1075 mSetSizeSignalV2.Emit( handle, size );
1080 void Actor::SetWidth( float width )
1084 // mNode is being used in a separate thread; queue a message to set the value & base value
1085 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1089 void Actor::SetHeight( float height )
1093 // mNode is being used in a separate thread; queue a message to set the value & base value
1094 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1098 void Actor::SetDepth( float depth )
1102 // mNode is being used in a separate thread; queue a message to set the value & base value
1103 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1107 const Vector3& Actor::GetCurrentSize() const
1111 // mNode is being used in a separate thread; copy the value from the previous update
1112 return mNode->GetSize( mStage->GetEventBufferIndex() );
1115 return Vector3::ZERO;
1118 void Actor::SetShaderEffect(ShaderEffect& effect)
1120 // no-op on an Actor
1123 ShaderEffectPtr Actor::GetShaderEffect() const
1125 return ShaderEffectPtr();
1128 void Actor::RemoveShaderEffect()
1132 #ifdef DYNAMICS_SUPPORT
1134 //--------------- Dynamics ---------------
1136 void Actor::DisableDynamics()
1138 if( NULL != mDynamicsData )
1140 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1142 // ensure dynamics object are disconnected from scene
1143 DisconnectDynamics();
1145 // delete joint owned by this actor
1146 while( !mDynamicsData->joints.empty() )
1148 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1151 // delete other joints referencing this actor
1152 while( !mDynamicsData->referencedJoints.empty() )
1154 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1155 ActorPtr jointOwner( joint->GetActor( true ) );
1158 jointOwner->RemoveDynamicsJoint( joint );
1162 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1165 // delete the DynamicsBody object
1166 mDynamicsData->body.Reset();
1168 // Discard Dynamics data structure
1169 delete mDynamicsData;
1170 mDynamicsData = NULL;
1174 DynamicsBodyPtr Actor::GetDynamicsBody() const
1176 DynamicsBodyPtr body;
1178 if( NULL != mDynamicsData )
1180 body = mDynamicsData->body;
1186 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1188 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1190 if( NULL == mDynamicsData )
1192 mDynamicsData = new DynamicsData( this );
1195 if( !mDynamicsData->body )
1197 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1201 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1204 if( mParent == world->GetRootActor().Get() )
1206 mDynamicsData->body->Connect(*mStage);
1212 return mDynamicsData->body;
1215 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1217 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1218 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1221 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1223 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1224 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1226 DynamicsJointPtr joint;
1228 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1232 if( NULL != mDynamicsData )
1234 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1236 if( mDynamicsData->joints.end() != it )
1238 // use existing joint
1244 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1245 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1249 bodyA = EnableDynamics( new DynamicsBodyConfig );
1254 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1257 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1258 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1260 if( OnStage() && attachedActor->OnStage() )
1262 joint->Connect(*mStage);
1265 attachedActor->ReferenceJoint( joint );
1267 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1268 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1275 const int Actor::GetNumberOfJoints() const
1277 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1280 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1282 DynamicsJointPtr joint;
1284 if( NULL != mDynamicsData )
1286 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1288 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1290 for( int i = 0; i < index; ++i )
1302 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1304 DynamicsJointPtr joint;
1306 if( NULL != mDynamicsData )
1308 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1310 if( mDynamicsData->joints.end() != it )
1312 // use existing joint
1320 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1322 if( NULL != mDynamicsData )
1324 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1325 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1327 for( ; it != endIt; ++it )
1329 if( it->second == joint.Get() )
1331 ActorPtr attachedActor( it->first );
1333 if( OnStage() && attachedActor && attachedActor->OnStage() )
1335 joint->Disconnect(*mStage);
1340 attachedActor->ReleaseJoint( joint );
1341 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1342 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1345 mDynamicsData->joints.erase(it);
1352 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1354 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1356 if( NULL != mDynamicsData )
1358 mDynamicsData->referencedJoints.push_back(joint);
1362 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1364 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1366 if( NULL != mDynamicsData )
1368 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1370 if( it != mDynamicsData->referencedJoints.end() )
1372 mDynamicsData->referencedJoints.erase( it );
1377 void Actor::SetDynamicsRoot(bool flag)
1379 if( mIsDynamicsRoot != flag )
1381 mIsDynamicsRoot = flag;
1383 if( OnStage() && mChildren )
1385 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1386 ActorIter end = mChildren->end();
1387 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1389 Actor& child = GetImplementation(*iter);
1391 if( child.GetDynamicsBody() )
1393 if( mIsDynamicsRoot )
1395 child.ConnectDynamics();
1399 child.DisconnectDynamics();
1407 bool Actor::IsDynamicsRoot() const
1409 return mIsDynamicsRoot;
1412 void Actor::AttachedActorOnStage( Dali::Actor actor )
1414 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1418 ActorPtr attachedActor( &GetImplementation(actor) );
1420 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1421 if( NULL != mDynamicsData )
1423 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1424 if( mDynamicsData->joints.end() != it )
1426 DynamicsJointPtr joint( it->second );
1427 joint->Connect(*mStage);
1433 void Actor::AttachedActorOffStage( Dali::Actor actor )
1435 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1439 ActorPtr attachedActor( &GetImplementation(actor) );
1441 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1442 if( NULL != mDynamicsData )
1444 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1445 if( mDynamicsData->joints.end() != it )
1447 DynamicsJointPtr joint( it->second );
1448 joint->Disconnect(*mStage);
1454 void Actor::ConnectDynamics()
1456 if( NULL != mDynamicsData && mDynamicsData->body )
1458 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1460 mDynamicsData->body->Connect(*mStage);
1462 // Connect all joints where attachedActor is also on stage
1463 if( !mDynamicsData->joints.empty() )
1465 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1466 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1468 for( ; it != endIt; ++it )
1470 Actor* attachedActor( it->first );
1471 if( NULL != attachedActor && attachedActor->OnStage() )
1473 DynamicsJointPtr joint( it->second );
1475 joint->Connect(*mStage);
1483 void Actor::DisconnectDynamics()
1485 if( NULL != mDynamicsData && mDynamicsData->body )
1489 mDynamicsData->body->Disconnect(*mStage);
1491 // Disconnect all joints
1492 if( !mDynamicsData->joints.empty() )
1494 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1495 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1497 for( ; it != endIt; ++it )
1499 DynamicsJointPtr joint( it->second );
1501 joint->Disconnect(*mStage);
1508 #endif // DYNAMICS_SUPPORT
1510 void Actor::SetOverlay(bool enable)
1512 // Setting STENCIL will override OVERLAY
1513 if( DrawMode::STENCIL != mDrawMode )
1515 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1519 bool Actor::IsOverlay() const
1521 return ( DrawMode::OVERLAY == mDrawMode );
1524 void Actor::SetDrawMode( DrawMode::Type drawMode )
1526 // this flag is not animatable so keep the value
1527 mDrawMode = drawMode;
1530 // mNode is being used in a separate thread; queue a message to set the value
1531 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1535 DrawMode::Type Actor::GetDrawMode() const
1540 bool Actor::ScreenToLocal( float& localX,
1543 float screenY ) const
1545 // only valid when on-stage
1548 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1550 Vector2 converted( screenX, screenY );
1552 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1553 const int taskCount = taskList.GetTaskCount();
1554 for( int i = taskCount - 1; i >= 0; --i )
1556 Dali::RenderTask task = taskList.GetTask( i );
1557 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1559 // found a task where this conversion was ok so return
1567 bool Actor::ScreenToLocal( RenderTask& renderTask,
1571 float screenY ) const
1573 bool retval = false;
1574 // only valid when on-stage
1577 CameraActor* camera = renderTask.GetCameraActor();
1581 renderTask.GetViewport( viewport );
1583 // need to translate coordinates to render tasks coordinate space
1584 Vector2 converted( screenX, screenY );
1585 if( renderTask.TranslateCoordinates( converted ) )
1587 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1594 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1595 const Matrix& projectionMatrix,
1596 const Viewport& viewport,
1600 float screenY ) const
1602 // Early-out if mNode is NULL
1608 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1610 // Calculate the ModelView matrix
1611 Matrix modelView(false/*don't init*/);
1612 // need to use the components as world matrix is only updated for actors that need it
1613 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1614 Matrix::Multiply(modelView, modelView, viewMatrix);
1616 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1617 Matrix invertedMvp(false/*don't init*/);
1618 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1619 bool success = invertedMvp.Invert();
1621 // Convert to GL coordinates
1622 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1627 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1634 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1640 if (XyPlaneIntersect(nearPos, farPos, local))
1642 Vector3 size = GetCurrentSize();
1643 localX = local.x + size.x * 0.5f;
1644 localY = local.y + size.y * 0.5f;
1655 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1658 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1660 Mathematical Formulation
1662 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1664 ( p - c ) dot ( p - c ) = r^2
1666 Given a ray with a point of origin 'o', and a direction vector 'd':
1668 ray(t) = o + td, t >= 0
1670 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1672 (o + td - c ) dot ( o + td - c ) = r^2
1674 To solve for t we first expand the above into a more recognisable quadratic equation form
1676 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1685 B = 2( o - c ) dot d
1686 C = ( o - c ) dot ( o - c ) - r^2
1688 which can be solved using a standard quadratic formula.
1690 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1692 Practical Simplification
1694 In a renderer, we often differentiate between world space and object space. In the object space
1695 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1696 into object space, the mathematical solution presented above can be simplified significantly.
1698 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1702 and we can find the t at which the (transformed) ray intersects the sphere by
1704 ( o + td ) dot ( o + td ) = r^2
1706 According to the reasoning above, we expand the above quadratic equation into the general form
1710 which now has coefficients:
1717 // Early out if mNode is NULL
1723 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1725 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1726 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1727 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1728 rayOrigin.y - translation.y,
1729 rayOrigin.z - translation.z);
1731 // Compute the radius is not needed, square radius it's enough.
1732 const Vector3& size( mNode->GetSize( bufferIndex ) );
1734 // Scale the sphere.
1735 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1737 const float width = size.width * scale.width;
1738 const float height = size.height * scale.height;
1740 float squareSphereRadius = 0.5f * ( width * width + height * height );
1742 float a = rayDir.Dot( rayDir ); // a
1743 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1744 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1746 return ( b2*b2 - a*c ) >= 0.f;
1749 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1756 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1758 // Transforms the ray to the local reference system.
1760 // Calculate the inverse of Model matrix
1761 Matrix invModelMatrix(false/*don't init*/);
1762 // need to use the components as world matrix is only updated for actors that need it
1763 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1765 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1766 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1768 // Test with the actor's XY plane (Normal = 0 0 1 1).
1770 float a = -rayOriginLocal.z;
1771 float b = rayDirLocal.z;
1773 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1775 // Ray travels distance * rayDirLocal to intersect with plane.
1778 const Vector3& size = mNode->GetSize( bufferIndex );
1780 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1781 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1783 // Test with the actor's geometry.
1784 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1791 void Actor::SetLeaveRequired(bool required)
1793 mLeaveRequired = required;
1796 bool Actor::GetLeaveRequired() const
1798 return mLeaveRequired;
1801 void Actor::SetKeyboardFocusable( bool focusable )
1803 mKeyboardFocusable = focusable;
1806 bool Actor::IsKeyboardFocusable() const
1808 return mKeyboardFocusable;
1811 bool Actor::GetTouchRequired() const
1813 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1816 bool Actor::GetMouseWheelEventRequired() const
1818 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1821 bool Actor::IsHittable() const
1823 return IsSensitive() &&
1825 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1829 ActorGestureData& Actor::GetGestureData()
1831 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1832 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1833 if ( NULL == mGestureData )
1835 mGestureData = new ActorGestureData;
1837 return *mGestureData;
1840 bool Actor::IsGestureRequred( Gesture::Type type ) const
1842 return mGestureData && mGestureData->IsGestureRequred( type );
1845 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1847 bool consumed = false;
1849 if ( !mTouchedSignalV2.Empty() )
1851 Dali::Actor handle( this );
1852 consumed = mTouchedSignalV2.Emit( handle, event );
1857 // Notification for derived classes
1858 consumed = OnTouchEvent( event );
1864 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1866 bool consumed = false;
1868 if ( !mMouseWheelEventSignalV2.Empty() )
1870 Dali::Actor handle( this );
1871 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1876 // Notification for derived classes
1877 consumed = OnMouseWheelEvent(event);
1883 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1885 return mTouchedSignalV2;
1888 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1890 return mMouseWheelEventSignalV2;
1893 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1895 return mSetSizeSignalV2;
1898 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1900 return mOnStageSignalV2;
1903 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1905 return mOffStageSignalV2;
1908 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1910 bool connected( true );
1911 Actor* actor = dynamic_cast<Actor*>(object);
1913 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1915 actor->TouchedSignal().Connect( tracker, functor );
1917 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1919 actor->MouseWheelEventSignal().Connect( tracker, functor );
1921 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1923 actor->SetSizeSignal().Connect( tracker, functor );
1925 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1927 actor->OnStageSignal().Connect( tracker, functor );
1929 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1931 actor->OffStageSignal().Connect( tracker, functor );
1935 // signalName does not match any signal
1942 Actor::Actor( DerivedType derivedType )
1947 mParentOrigin( NULL ),
1948 mAnchorPoint( NULL ),
1949 #ifdef DYNAMICS_SUPPORT
1950 mDynamicsData( NULL ),
1952 mGestureData( NULL ),
1955 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1956 mIsRoot( ROOT_LAYER == derivedType ),
1957 mIsRenderable( RENDERABLE == derivedType ),
1958 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1959 mIsOnStage( false ),
1960 mIsDynamicsRoot(false),
1962 mLeaveRequired( false ),
1963 mKeyboardFocusable( false ),
1964 mDerivedRequiresTouch( false ),
1965 mDerivedRequiresMouseWheelEvent( false ),
1966 mOnStageSignalled( false ),
1967 mInheritRotation( true ),
1968 mInheritScale( true ),
1969 mDrawMode( DrawMode::NORMAL ),
1970 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1971 mColorMode( Node::DEFAULT_COLOR_MODE )
1975 void Actor::Initialize()
1977 mStage = Stage::GetCurrent();
1980 SceneGraph::Node* node = CreateNode();
1982 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
1983 mNode = node; // Keep raw-pointer to Node
1985 if(!mDefaultPropertyLookup)
1987 mDefaultPropertyLookup = new DefaultPropertyLookup();
1989 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
1991 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
2002 // Remove mParent pointers from children even if we're destroying core,
2003 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
2006 ActorConstIter endIter = mChildren->end();
2007 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2009 Actor& actor = GetImplementation( *iter );
2010 actor.SetParent( NULL );
2015 // Guard to allow handle destruction after Core has been destroyed
2016 if( Stage::IsInstalled() )
2020 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2021 mNode = NULL; // Node is about to be destroyed
2027 #ifdef DYNAMICS_SUPPORT
2029 delete mDynamicsData;
2032 // Cleanup optional gesture data
2033 delete mGestureData;
2035 // Cleanup optional parent origin and anchor
2036 delete mParentOrigin;
2037 delete mAnchorPoint;
2040 void Actor::ConnectToStage( Stage& stage )
2042 // This container is used instead of walking the Actor hierachy.
2043 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2044 ActorContainer connectionList;
2046 // This stage is atomic i.e. not interrupted by user callbacks
2047 RecursiveConnectToStage( stage, connectionList );
2049 // Notify applications about the newly connected actors.
2050 const ActorIter endIter = connectionList.end();
2051 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2053 Actor& actor = GetImplementation(*iter);
2054 actor.NotifyStageConnection();
2058 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2060 DALI_ASSERT_ALWAYS( !OnStage() );
2064 ConnectToSceneGraph();
2066 // Notification for internal derived classes
2067 OnStageConnectionInternal();
2069 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2070 connectionList.push_back( Dali::Actor(this) );
2072 // Recursively connect children
2075 ActorConstIter endIter = mChildren->end();
2076 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2078 Actor& actor = GetImplementation( *iter );
2079 actor.RecursiveConnectToStage( stage, connectionList );
2085 * This method is called when the Actor is connected to the Stage.
2086 * The parent must have added its Node to the scene-graph.
2087 * The child must connect its Node to the parent's Node.
2088 * This is resursive; the child calls ConnectToStage() for its children.
2090 void Actor::ConnectToSceneGraph()
2092 DALI_ASSERT_DEBUG( mNode != NULL);
2093 DALI_ASSERT_DEBUG( mParent != NULL);
2094 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2098 // Reparent Node in next Update
2099 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2102 // Notify attachment
2105 mAttachment->Connect();
2108 #ifdef DYNAMICS_SUPPORT
2110 if( NULL != mDynamicsData )
2116 // Notification for ProxyObject::Observers
2120 void Actor::NotifyStageConnection()
2122 // Actors can be removed (in a callback), before the on-stage stage is reported.
2123 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2124 if ( OnStage() && !mOnStageSignalled )
2126 // Notification for external (CustomActor) derived classes
2127 OnStageConnectionExternal();
2129 if ( !mOnStageSignalV2.Empty() )
2131 Dali::Actor handle( this );
2132 mOnStageSignalV2.Emit( handle );
2135 // Guard against Remove during callbacks
2138 mOnStageSignalled = true; // signal required next time Actor is removed
2143 void Actor::DisconnectFromStage()
2145 // This container is used instead of walking the Actor hierachy.
2146 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2147 ActorContainer disconnectionList;
2149 // This stage is atomic i.e. not interrupted by user callbacks
2150 RecursiveDisconnectFromStage( disconnectionList );
2152 // Notify applications about the newly disconnected actors.
2153 const ActorIter endIter = disconnectionList.end();
2154 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2156 Actor& actor = GetImplementation(*iter);
2157 actor.NotifyStageDisconnection();
2161 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2163 DALI_ASSERT_ALWAYS( OnStage() );
2165 // Recursively disconnect children
2168 ActorConstIter endIter = mChildren->end();
2169 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2171 Actor& actor = GetImplementation( *iter );
2172 actor.RecursiveDisconnectFromStage( disconnectionList );
2176 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2177 disconnectionList.push_back( Dali::Actor(this) );
2179 // Notification for internal derived classes
2180 OnStageDisconnectionInternal();
2182 DisconnectFromSceneGraph();
2188 * This method is called by an actor or its parent, before a node removal message is sent.
2189 * This is recursive; the child calls DisconnectFromStage() for its children.
2191 void Actor::DisconnectFromSceneGraph()
2193 // Notification for ProxyObject::Observers
2194 OnSceneObjectRemove();
2196 // Notify attachment
2199 mAttachment->Disconnect();
2202 #ifdef DYNAMICS_SUPPORT
2204 if( NULL != mDynamicsData )
2206 DisconnectDynamics();
2211 void Actor::NotifyStageDisconnection()
2213 // Actors can be added (in a callback), before the off-stage state is reported.
2214 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2215 // only do this step if there is a stage, i.e. Core is not being shut down
2216 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2218 // Notification for external (CustomeActor) derived classes
2219 OnStageDisconnectionExternal();
2221 if( !mOffStageSignalV2.Empty() )
2223 Dali::Actor handle( this );
2224 mOffStageSignalV2.Emit( handle );
2227 // Guard against Add during callbacks
2230 mOnStageSignalled = false; // signal required next time Actor is added
2235 bool Actor::IsNodeConnected() const
2237 bool connected( false );
2242 if( mNode->IsRoot() || mNode->GetParent() )
2251 bool Actor::IsSceneObjectRemovable() const
2256 unsigned int Actor::GetDefaultPropertyCount() const
2258 return DEFAULT_PROPERTY_COUNT;
2261 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2263 indices.reserve( DEFAULT_PROPERTY_COUNT );
2265 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2267 indices.push_back( i );
2271 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2273 if( index < DEFAULT_PROPERTY_COUNT )
2275 return DEFAULT_PROPERTY_DETAILS[index].name;
2279 // index out of range..return empty string
2280 return String::EMPTY;
2284 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2286 Property::Index index = Property::INVALID_INDEX;
2288 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2290 // Look for name in default properties
2291 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2292 if ( mDefaultPropertyLookup->end() != result )
2294 index = result->second;
2300 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2302 if( index < DEFAULT_PROPERTY_COUNT )
2304 return DEFAULT_PROPERTY_DETAILS[index].writable;
2312 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2314 if( index < DEFAULT_PROPERTY_COUNT )
2316 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2324 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2326 if( index < DEFAULT_PROPERTY_COUNT )
2328 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2336 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2338 if( index < DEFAULT_PROPERTY_COUNT )
2340 return DEFAULT_PROPERTY_DETAILS[index].type;
2344 // index out of range...return Property::NONE
2345 return Property::NONE;
2349 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2353 case Dali::Actor::PARENT_ORIGIN:
2355 SetParentOrigin( property.Get<Vector3>() );
2359 case Dali::Actor::PARENT_ORIGIN_X:
2361 SetParentOriginX( property.Get<float>() );
2365 case Dali::Actor::PARENT_ORIGIN_Y:
2367 SetParentOriginY( property.Get<float>() );
2371 case Dali::Actor::PARENT_ORIGIN_Z:
2373 SetParentOriginZ( property.Get<float>() );
2377 case Dali::Actor::ANCHOR_POINT:
2379 SetAnchorPoint( property.Get<Vector3>() );
2383 case Dali::Actor::ANCHOR_POINT_X:
2385 SetAnchorPointX( property.Get<float>() );
2389 case Dali::Actor::ANCHOR_POINT_Y:
2391 SetAnchorPointY( property.Get<float>() );
2395 case Dali::Actor::ANCHOR_POINT_Z:
2397 SetAnchorPointZ( property.Get<float>() );
2401 case Dali::Actor::SIZE:
2403 SetSize( property.Get<Vector3>() );
2407 case Dali::Actor::SIZE_WIDTH:
2409 SetWidth( property.Get<float>() );
2413 case Dali::Actor::SIZE_HEIGHT:
2415 SetHeight( property.Get<float>() );
2419 case Dali::Actor::SIZE_DEPTH:
2421 SetDepth( property.Get<float>() );
2425 case Dali::Actor::POSITION:
2427 SetPosition( property.Get<Vector3>() );
2431 case Dali::Actor::POSITION_X:
2433 SetX( property.Get<float>() );
2437 case Dali::Actor::POSITION_Y:
2439 SetY( property.Get<float>() );
2443 case Dali::Actor::POSITION_Z:
2445 SetZ( property.Get<float>() );
2449 case Dali::Actor::ROTATION:
2451 SetRotation( property.Get<Quaternion>() );
2455 case Dali::Actor::SCALE:
2457 SetScale( property.Get<Vector3>() );
2461 case Dali::Actor::SCALE_X:
2463 SetScaleX( property.Get<float>() );
2467 case Dali::Actor::SCALE_Y:
2469 SetScaleY( property.Get<float>() );
2473 case Dali::Actor::SCALE_Z:
2475 SetScaleZ( property.Get<float>() );
2479 case Dali::Actor::VISIBLE:
2481 SetVisible( property.Get<bool>() );
2485 case Dali::Actor::COLOR:
2487 SetColor( property.Get<Vector4>() );
2491 case Dali::Actor::COLOR_RED:
2493 SetColorRed( property.Get<float>() );
2497 case Dali::Actor::COLOR_GREEN:
2499 SetColorGreen( property.Get<float>() );
2503 case Dali::Actor::COLOR_BLUE:
2505 SetColorBlue( property.Get<float>() );
2509 case Dali::Actor::COLOR_ALPHA:
2511 SetOpacity( property.Get<float>() );
2515 case Dali::Actor::NAME:
2517 SetName( property.Get<std::string>() );
2521 case Dali::Actor::SENSITIVE:
2523 SetSensitive( property.Get<bool>() );
2527 case Dali::Actor::LEAVE_REQUIRED:
2529 SetLeaveRequired( property.Get<bool>() );
2533 case Dali::Actor::INHERIT_ROTATION:
2535 SetInheritRotation( property.Get<bool>() );
2539 case Dali::Actor::INHERIT_SCALE:
2541 SetInheritScale( property.Get<bool>() );
2545 case Dali::Actor::COLOR_MODE:
2547 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2551 case Dali::Actor::POSITION_INHERITANCE:
2553 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2557 case Dali::Actor::DRAW_MODE:
2559 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2565 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2571 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2573 // TODO: This should be deprecated
2574 OnPropertySet(index, value);
2576 if(entry.IsAnimatable())
2578 // TODO: ADD MATRIX & MATRIX3 types
2580 switch ( entry.type )
2582 case Property::BOOLEAN:
2584 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2585 DALI_ASSERT_DEBUG( NULL != property );
2587 // property is being used in a separate thread; queue a message to set the property
2588 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2593 case Property::FLOAT:
2595 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2596 DALI_ASSERT_DEBUG( NULL != property );
2598 // property is being used in a separate thread; queue a message to set the property
2599 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2604 case Property::INTEGER:
2606 AnimatableProperty<int>* property = dynamic_cast< AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2607 DALI_ASSERT_DEBUG( NULL != property );
2609 // property is being used in a separate thread; queue a message to set the property
2610 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2615 case Property::VECTOR2:
2617 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2618 DALI_ASSERT_DEBUG( NULL != property );
2620 // property is being used in a separate thread; queue a message to set the property
2621 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2626 case Property::VECTOR3:
2628 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2629 DALI_ASSERT_DEBUG( NULL != property );
2631 // property is being used in a separate thread; queue a message to set the property
2632 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2637 case Property::VECTOR4:
2639 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2640 DALI_ASSERT_DEBUG( NULL != property );
2642 // property is being used in a separate thread; queue a message to set the property
2643 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2648 case Property::ROTATION:
2650 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2651 DALI_ASSERT_DEBUG( NULL != property );
2653 // property is being used in a separate thread; queue a message to set the property
2654 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2661 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2668 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2670 Property::Value value;
2674 case Dali::Actor::PARENT_ORIGIN:
2676 value = GetCurrentParentOrigin();
2680 case Dali::Actor::PARENT_ORIGIN_X:
2682 value = GetCurrentParentOrigin().x;
2686 case Dali::Actor::PARENT_ORIGIN_Y:
2688 value = GetCurrentParentOrigin().y;
2692 case Dali::Actor::PARENT_ORIGIN_Z:
2694 value = GetCurrentParentOrigin().z;
2698 case Dali::Actor::ANCHOR_POINT:
2700 value = GetCurrentAnchorPoint();
2704 case Dali::Actor::ANCHOR_POINT_X:
2706 value = GetCurrentAnchorPoint().x;
2710 case Dali::Actor::ANCHOR_POINT_Y:
2712 value = GetCurrentAnchorPoint().y;
2716 case Dali::Actor::ANCHOR_POINT_Z:
2718 value = GetCurrentAnchorPoint().z;
2722 case Dali::Actor::SIZE:
2724 value = GetCurrentSize();
2728 case Dali::Actor::SIZE_WIDTH:
2730 value = GetCurrentSize().width;
2734 case Dali::Actor::SIZE_HEIGHT:
2736 value = GetCurrentSize().height;
2740 case Dali::Actor::SIZE_DEPTH:
2742 value = GetCurrentSize().depth;
2746 case Dali::Actor::POSITION:
2748 value = GetCurrentPosition();
2752 case Dali::Actor::POSITION_X:
2754 value = GetCurrentPosition().x;
2758 case Dali::Actor::POSITION_Y:
2760 value = GetCurrentPosition().y;
2764 case Dali::Actor::POSITION_Z:
2766 value = GetCurrentPosition().z;
2770 case Dali::Actor::WORLD_POSITION:
2772 value = GetCurrentWorldPosition();
2776 case Dali::Actor::WORLD_POSITION_X:
2778 value = GetCurrentWorldPosition().x;
2782 case Dali::Actor::WORLD_POSITION_Y:
2784 value = GetCurrentWorldPosition().y;
2788 case Dali::Actor::WORLD_POSITION_Z:
2790 value = GetCurrentWorldPosition().z;
2794 case Dali::Actor::ROTATION:
2796 value = GetCurrentRotation();
2800 case Dali::Actor::WORLD_ROTATION:
2802 value = GetCurrentWorldRotation();
2806 case Dali::Actor::SCALE:
2808 value = GetCurrentScale();
2812 case Dali::Actor::SCALE_X:
2814 value = GetCurrentScale().x;
2818 case Dali::Actor::SCALE_Y:
2820 value = GetCurrentScale().y;
2824 case Dali::Actor::SCALE_Z:
2826 value = GetCurrentScale().z;
2830 case Dali::Actor::WORLD_SCALE:
2832 value = GetCurrentWorldScale();
2836 case Dali::Actor::VISIBLE:
2838 value = IsVisible();
2842 case Dali::Actor::COLOR:
2844 value = GetCurrentColor();
2848 case Dali::Actor::COLOR_RED:
2850 value = GetCurrentColor().r;
2854 case Dali::Actor::COLOR_GREEN:
2856 value = GetCurrentColor().g;
2860 case Dali::Actor::COLOR_BLUE:
2862 value = GetCurrentColor().b;
2866 case Dali::Actor::COLOR_ALPHA:
2868 value = GetCurrentColor().a;
2872 case Dali::Actor::WORLD_COLOR:
2874 value = GetCurrentWorldColor();
2878 case Dali::Actor::WORLD_MATRIX:
2880 value = GetCurrentWorldMatrix();
2884 case Dali::Actor::NAME:
2890 case Dali::Actor::SENSITIVE:
2892 value = IsSensitive();
2896 case Dali::Actor::LEAVE_REQUIRED:
2898 value = GetLeaveRequired();
2902 case Dali::Actor::INHERIT_ROTATION:
2904 value = IsRotationInherited();
2908 case Dali::Actor::INHERIT_SCALE:
2910 value = IsScaleInherited();
2914 case Dali::Actor::COLOR_MODE:
2916 value = Scripting::GetColorMode( GetColorMode() );
2920 case Dali::Actor::POSITION_INHERITANCE:
2922 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2926 case Dali::Actor::DRAW_MODE:
2928 value = Scripting::GetDrawMode( GetDrawMode() );
2934 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2942 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2946 // mNode is being used in a separate thread; queue a message to add the property
2947 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
2951 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2953 // This method should only return an object connected to the scene-graph
2954 return OnStage() ? mNode : NULL;
2957 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2959 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2961 const PropertyBase* property( NULL );
2963 // This method should only return a property of an object connected to the scene-graph
2969 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
2971 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
2973 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
2975 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
2977 else if( NULL != mNode )
2981 case Dali::Actor::SIZE:
2982 property = &mNode->mSize;
2985 case Dali::Actor::SIZE_WIDTH:
2986 property = &mNode->mSize;
2989 case Dali::Actor::SIZE_HEIGHT:
2990 property = &mNode->mSize;
2993 case Dali::Actor::SIZE_DEPTH:
2994 property = &mNode->mSize;
2997 case Dali::Actor::POSITION:
2998 property = &mNode->mPosition;
3001 case Dali::Actor::POSITION_X:
3002 property = &mNode->mPosition;
3005 case Dali::Actor::POSITION_Y:
3006 property = &mNode->mPosition;
3009 case Dali::Actor::POSITION_Z:
3010 property = &mNode->mPosition;
3013 case Dali::Actor::ROTATION:
3014 property = &mNode->mRotation;
3017 case Dali::Actor::SCALE:
3018 property = &mNode->mScale;
3021 case Dali::Actor::SCALE_X:
3022 property = &mNode->mScale;
3025 case Dali::Actor::SCALE_Y:
3026 property = &mNode->mScale;
3029 case Dali::Actor::SCALE_Z:
3030 property = &mNode->mScale;
3033 case Dali::Actor::VISIBLE:
3034 property = &mNode->mVisible;
3037 case Dali::Actor::COLOR:
3038 property = &mNode->mColor;
3041 case Dali::Actor::COLOR_RED:
3042 property = &mNode->mColor;
3045 case Dali::Actor::COLOR_GREEN:
3046 property = &mNode->mColor;
3049 case Dali::Actor::COLOR_BLUE:
3050 property = &mNode->mColor;
3053 case Dali::Actor::COLOR_ALPHA:
3054 property = &mNode->mColor;
3065 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3067 const PropertyInputImpl* property( NULL );
3069 // This method should only return a property of an object connected to the scene-graph
3075 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3077 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3079 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3081 property = entry->second.GetSceneGraphProperty();
3083 else if( NULL != mNode )
3087 case Dali::Actor::PARENT_ORIGIN:
3088 property = &mNode->mParentOrigin;
3091 case Dali::Actor::PARENT_ORIGIN_X:
3092 property = &mNode->mParentOrigin;
3095 case Dali::Actor::PARENT_ORIGIN_Y:
3096 property = &mNode->mParentOrigin;
3099 case Dali::Actor::PARENT_ORIGIN_Z:
3100 property = &mNode->mParentOrigin;
3103 case Dali::Actor::ANCHOR_POINT:
3104 property = &mNode->mAnchorPoint;
3107 case Dali::Actor::ANCHOR_POINT_X:
3108 property = &mNode->mAnchorPoint;
3111 case Dali::Actor::ANCHOR_POINT_Y:
3112 property = &mNode->mAnchorPoint;
3115 case Dali::Actor::ANCHOR_POINT_Z:
3116 property = &mNode->mAnchorPoint;
3119 case Dali::Actor::SIZE:
3120 property = &mNode->mSize;
3123 case Dali::Actor::SIZE_WIDTH:
3124 property = &mNode->mSize;
3127 case Dali::Actor::SIZE_HEIGHT:
3128 property = &mNode->mSize;
3131 case Dali::Actor::SIZE_DEPTH:
3132 property = &mNode->mSize;
3135 case Dali::Actor::POSITION:
3136 property = &mNode->mPosition;
3139 case Dali::Actor::POSITION_X:
3140 property = &mNode->mPosition;
3143 case Dali::Actor::POSITION_Y:
3144 property = &mNode->mPosition;
3147 case Dali::Actor::POSITION_Z:
3148 property = &mNode->mPosition;
3151 case Dali::Actor::WORLD_POSITION:
3152 property = &mNode->mWorldPosition;
3155 case Dali::Actor::WORLD_POSITION_X:
3156 property = &mNode->mWorldPosition;
3159 case Dali::Actor::WORLD_POSITION_Y:
3160 property = &mNode->mWorldPosition;
3163 case Dali::Actor::WORLD_POSITION_Z:
3164 property = &mNode->mWorldPosition;
3167 case Dali::Actor::ROTATION:
3168 property = &mNode->mRotation;
3171 case Dali::Actor::WORLD_ROTATION:
3172 property = &mNode->mWorldRotation;
3175 case Dali::Actor::SCALE:
3176 property = &mNode->mScale;
3179 case Dali::Actor::SCALE_X:
3180 property = &mNode->mScale;
3183 case Dali::Actor::SCALE_Y:
3184 property = &mNode->mScale;
3187 case Dali::Actor::SCALE_Z:
3188 property = &mNode->mScale;
3191 case Dali::Actor::WORLD_SCALE:
3192 property = &mNode->mWorldScale;
3195 case Dali::Actor::VISIBLE:
3196 property = &mNode->mVisible;
3199 case Dali::Actor::COLOR:
3200 property = &mNode->mColor;
3203 case Dali::Actor::COLOR_RED:
3204 property = &mNode->mColor;
3207 case Dali::Actor::COLOR_GREEN:
3208 property = &mNode->mColor;
3211 case Dali::Actor::COLOR_BLUE:
3212 property = &mNode->mColor;
3215 case Dali::Actor::COLOR_ALPHA:
3216 property = &mNode->mColor;
3219 case Dali::Actor::WORLD_COLOR:
3220 property = &mNode->mWorldColor;
3223 case Dali::Actor::WORLD_MATRIX:
3224 property = &mNode->mWorldMatrix;
3235 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3237 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3241 case Dali::Actor::PARENT_ORIGIN_X:
3242 case Dali::Actor::ANCHOR_POINT_X:
3243 case Dali::Actor::SIZE_WIDTH:
3244 case Dali::Actor::POSITION_X:
3245 case Dali::Actor::SCALE_X:
3246 case Dali::Actor::COLOR_RED:
3247 case Dali::Actor::WORLD_POSITION_X:
3253 case Dali::Actor::PARENT_ORIGIN_Y:
3254 case Dali::Actor::ANCHOR_POINT_Y:
3255 case Dali::Actor::SIZE_HEIGHT:
3256 case Dali::Actor::POSITION_Y:
3257 case Dali::Actor::SCALE_Y:
3258 case Dali::Actor::COLOR_GREEN:
3259 case Dali::Actor::WORLD_POSITION_Y:
3265 case Dali::Actor::PARENT_ORIGIN_Z:
3266 case Dali::Actor::ANCHOR_POINT_Z:
3267 case Dali::Actor::SIZE_DEPTH:
3268 case Dali::Actor::POSITION_Z:
3269 case Dali::Actor::SCALE_Z:
3270 case Dali::Actor::COLOR_BLUE:
3271 case Dali::Actor::WORLD_POSITION_Z:
3277 case Dali::Actor::COLOR_ALPHA:
3290 return componentIndex;
3293 void Actor::SetParent(Actor* parent)
3297 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3301 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3304 StagePtr stage = parent->mStage;
3306 // Instruct each actor to create a corresponding node in the scene graph
3307 ConnectToStage(*stage);
3310 else // parent being set to NULL
3312 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3316 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3319 DALI_ASSERT_ALWAYS(mNode != NULL);
3323 // Disconnect the Node & its children from the scene-graph.
3324 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3327 // Instruct each actor to discard pointers to the scene-graph
3328 DisconnectFromStage();
3333 SceneGraph::Node* Actor::CreateNode() const
3338 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3341 Actor* actor = dynamic_cast<Actor*>(object);
3345 if(Dali::Actor::ACTION_SHOW == actionName)
3347 actor->SetVisible(true);
3350 else if(Dali::Actor::ACTION_HIDE == actionName)
3352 actor->SetVisible(false);
3360 } // namespace Internal