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::Remove(Actor& child)
336 DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
346 // Find the child in mChildren, and unparent it
347 ActorIter end = mChildren->end();
348 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
350 Actor& actor = GetImplementation(*iter);
352 if( &actor == &child )
354 // Keep handle for OnChildRemove notification
355 removed = Dali::Actor( &actor );
357 // Do this first, since user callbacks from within SetParent() may need to add the child
358 mChildren->erase(iter);
360 DALI_ASSERT_DEBUG( actor.GetParent() == this );
361 actor.SetParent( NULL );
369 // Notification for derived classes
370 OnChildRemove( GetImplementation(removed) );
374 void Actor::Unparent()
378 mParent->Remove( *this );
382 unsigned int Actor::GetChildCount() const
384 return ( NULL != mChildren ) ? mChildren->size() : 0;
387 Dali::Actor Actor::GetChildAt(unsigned int index) const
389 DALI_ASSERT_ALWAYS( index < GetChildCount() );
391 return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
394 ActorContainer Actor::GetChildren()
396 if( NULL != mChildren )
401 // return copy of mNullChildren
402 return mNullChildren;
405 const ActorContainer& Actor::GetChildren() const
407 if( NULL != mChildren )
412 // return const reference to mNullChildren
413 return mNullChildren;
416 ActorPtr Actor::FindChildByName(const std::string& actorName)
419 if (actorName == mName)
425 ActorIter end = mChildren->end();
426 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
428 child = GetImplementation(*iter).FindChildByName(actorName);
439 Dali::Actor Actor::FindChildByAlias(const std::string& actorAlias)
441 Dali::Actor child = DoGetChildByAlias(actorAlias);
443 // If not found then search by name.
446 Internal::ActorPtr child_ptr = FindChildByName(actorAlias);
449 child = Dali::Actor(child_ptr.Get());
456 Dali::Actor Actor::DoGetChildByAlias(const std::string& actorAlias)
458 Dali::Actor child = GetChildByAlias(actorAlias);
460 if (!child && mChildren )
462 ActorIter end = mChildren->end();
463 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
465 child = GetImplementation(*iter).DoGetChildByAlias(actorAlias);
477 ActorPtr Actor::FindChildById(const unsigned int id)
486 ActorIter end = mChildren->end();
487 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
489 child = GetImplementation(*iter).FindChildById(id);
500 void Actor::SetParentOrigin( const Vector3& origin )
504 // mNode is being used in a separate thread; queue a message to set the value & base value
505 SetParentOriginMessage( mStage->GetUpdateInterface(), *mNode, origin );
508 // Cache for event-thread access
511 // not allocated, check if different from default
512 if( ParentOrigin::DEFAULT != origin )
514 mParentOrigin = new Vector3( origin );
519 // check if different from current costs more than just set
520 *mParentOrigin = origin;
524 void Actor::SetParentOriginX( float x )
526 const Vector3& current = GetCurrentParentOrigin();
528 SetParentOrigin( Vector3( x, current.y, current.z ) );
531 void Actor::SetParentOriginY( float y )
533 const Vector3& current = GetCurrentParentOrigin();
535 SetParentOrigin( Vector3( current.x, y, current.z ) );
538 void Actor::SetParentOriginZ( float z )
540 const Vector3& current = GetCurrentParentOrigin();
542 SetParentOrigin( Vector3( current.x, current.y, z ) );
545 const Vector3& Actor::GetCurrentParentOrigin() const
547 // Cached for event-thread access
548 return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
551 void Actor::SetAnchorPoint(const Vector3& anchor)
555 // mNode is being used in a separate thread; queue a message to set the value & base value
556 SetAnchorPointMessage( mStage->GetUpdateInterface(), *mNode, anchor );
559 // Cache for event-thread access
562 // not allocated, check if different from default
563 if( AnchorPoint::DEFAULT != anchor )
565 mAnchorPoint = new Vector3( anchor );
570 // check if different from current costs more than just set
571 *mAnchorPoint = anchor;
575 void Actor::SetAnchorPointX( float x )
577 const Vector3& current = GetCurrentAnchorPoint();
579 SetAnchorPoint( Vector3( x, current.y, current.z ) );
582 void Actor::SetAnchorPointY( float y )
584 const Vector3& current = GetCurrentAnchorPoint();
586 SetAnchorPoint( Vector3( current.x, y, current.z ) );
589 void Actor::SetAnchorPointZ( float z )
591 const Vector3& current = GetCurrentAnchorPoint();
593 SetAnchorPoint( Vector3( current.x, current.y, z ) );
596 const Vector3& Actor::GetCurrentAnchorPoint() const
598 // Cached for event-thread access
599 return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
602 void Actor::SetPosition(float x, float y)
604 SetPosition(Vector3(x, y, 0.0f));
607 void Actor::SetPosition(float x, float y, float z)
609 SetPosition(Vector3(x, y, z));
612 void Actor::SetPosition(const Vector3& position)
616 // mNode is being used in a separate thread; queue a message to set the value & base value
617 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
621 void Actor::SetX(float x)
625 // mNode is being used in a separate thread; queue a message to set the value & base value
626 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeX, x );
630 void Actor::SetY(float y)
634 // mNode is being used in a separate thread; queue a message to set the value & base value
635 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeY, y );
639 void Actor::SetZ(float z)
643 // mNode is being used in a separate thread; queue a message to set the value & base value
644 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeZ, z );
648 void Actor::MoveBy(const Vector3& distance)
652 // mNode is being used in a separate thread; queue a message to set the value & base value
653 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::BakeRelative, distance );
657 const Vector3& Actor::GetCurrentPosition() const
661 // mNode is being used in a separate thread; copy the value from the previous update
662 return mNode->GetPosition(mStage->GetEventBufferIndex());
665 return Vector3::ZERO;
668 const Vector3& Actor::GetCurrentWorldPosition() const
672 // mNode is being used in a separate thread; copy the value from the previous update
673 return mNode->GetWorldPosition( mStage->GetEventBufferIndex() );
676 return Vector3::ZERO;
679 void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode )
681 // this flag is not animatable so keep the value
682 mPositionInheritanceMode = mode;
685 // mNode is being used in a separate thread; queue a message to set the value
686 SetPositionInheritanceModeMessage( mStage->GetUpdateInterface(), *mNode, mode );
690 PositionInheritanceMode Actor::GetPositionInheritanceMode() const
692 // Cached for event-thread access
693 return mPositionInheritanceMode;
696 void Actor::SetRotation(const Radian& angle, const Vector3& axis)
698 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
699 normalizedAxis.Normalize();
701 Quaternion rotation(Quaternion::FromAxisAngle(normalizedAxis, angle));
703 SetRotation(rotation);
706 void Actor::SetRotation(const Quaternion& rotation)
710 // mNode is being used in a separate thread; queue a message to set the value & base value
711 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::Bake, rotation );
715 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
719 // mNode is being used in a separate thread; queue a message to set the value & base value
720 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, Quaternion(angle, axis) );
724 void Actor::RotateBy(const Quaternion& relativeRotation)
728 // mNode is being used in a separate thread; queue a message to set the value & base value
729 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, &mNode->mRotation, &AnimatableProperty<Quaternion>::BakeRelative, relativeRotation );
733 const Quaternion& Actor::GetCurrentRotation() const
737 // mNode is being used in a separate thread; copy the value from the previous update
738 return mNode->GetRotation(mStage->GetEventBufferIndex());
741 return Quaternion::IDENTITY;
744 const Quaternion& Actor::GetCurrentWorldRotation() const
748 // mNode is being used in a separate thread; copy the value from the previous update
749 return mNode->GetWorldRotation( mStage->GetEventBufferIndex() );
752 return Quaternion::IDENTITY;
755 void Actor::SetScale(float scale)
757 SetScale(Vector3(scale, scale, scale));
760 void Actor::SetScale(float x, float y, float z)
762 SetScale(Vector3(x, y, z));
765 void Actor::SetScale(const Vector3& scale)
769 // mNode is being used in a separate thread; queue a message to set the value & base value
770 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::Bake, scale );
774 void Actor::SetScaleX( float x )
778 // mNode is being used in a separate thread; queue a message to set the value & base value
779 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeX, x );
783 void Actor::SetScaleY( float y )
787 // mNode is being used in a separate thread; queue a message to set the value & base value
788 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeY, y );
792 void Actor::SetScaleZ( float z )
796 // mNode is being used in a separate thread; queue a message to set the value & base value
797 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeZ, z );
801 void Actor::SetInitialVolume(const Vector3& volume)
805 // mNode is being used in a separate thread; queue a message to set the value
806 SetInitialVolumeMessage( mStage->GetUpdateInterface(), *mNode, volume );
810 void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
814 // mNode is being used in a separate thread; queue a message to set the value
815 SetTransmitGeometryScalingMessage( mStage->GetUpdateInterface(), *mNode, transmitGeometryScaling );
819 bool Actor::GetTransmitGeometryScaling() const
823 // mNode is being used in a separate thread; copy the value from the previous update
824 return mNode->GetTransmitGeometryScaling();
830 void Actor::ScaleBy(const Vector3& relativeScale)
834 // mNode is being used in a separate thread; queue a message to set the value & base value
835 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mScale, &AnimatableProperty<Vector3>::BakeRelativeMultiply, relativeScale );
839 const Vector3& Actor::GetCurrentScale() const
843 // mNode is being used in a separate thread; copy the value from the previous update
844 return mNode->GetScale(mStage->GetEventBufferIndex());
850 const Vector3& Actor::GetCurrentWorldScale() const
854 // mNode is being used in a separate thread; copy the value from the previous update
855 return mNode->GetWorldScale( mStage->GetEventBufferIndex() );
861 void Actor::SetInheritScale( bool inherit )
863 // non animateable so keep local copy
864 mInheritScale = inherit;
867 // mNode is being used in a separate thread; queue a message to set the value
868 SetInheritScaleMessage( mStage->GetUpdateInterface(), *mNode, inherit );
872 bool Actor::IsScaleInherited() const
874 return mInheritScale;
877 Matrix Actor::GetCurrentWorldMatrix() const
881 // World matrix is no longer updated unless there is something observing the node.
882 // Need to calculate it from node's world position, rotation and scale:
883 BufferIndex updateBufferIndex = mStage->GetEventBufferIndex();
884 Matrix worldMatrix(false);
885 worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ),
886 mNode->GetWorldRotation( updateBufferIndex ),
887 mNode->GetWorldPosition( updateBufferIndex ) );
891 return Matrix::IDENTITY;
894 void Actor::SetVisible(bool visible)
898 // mNode is being used in a separate thread; queue a message to set the value & base value
899 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
903 bool Actor::IsVisible() const
907 // mNode is being used in a separate thread; copy the value from the previous update
908 return mNode->IsVisible( mStage->GetEventBufferIndex() );
914 void Actor::SetOpacity(float opacity)
918 // mNode is being used in a separate thread; queue a message to set the value & base value
919 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
923 void Actor::OpacityBy(float relativeOpacity)
927 // mNode is being used in a separate thread; queue a message to set the value & base value
928 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeWRelative, relativeOpacity );
932 float Actor::GetCurrentOpacity() const
936 // mNode is being used in a separate thread; copy the value from the previous update
937 return mNode->GetOpacity(mStage->GetEventBufferIndex());
943 const Vector4& Actor::GetCurrentWorldColor() const
947 return mNode->GetWorldColor( mStage->GetEventBufferIndex() );
953 void Actor::SetColor(const Vector4& color)
957 // mNode is being used in a separate thread; queue a message to set the value & base value
958 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::Bake, color );
962 void Actor::SetColorRed( float red )
966 // mNode is being used in a separate thread; queue a message to set the value & base value
967 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeX, red );
971 void Actor::SetColorGreen( float green )
975 // mNode is being used in a separate thread; queue a message to set the value & base value
976 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeY, green );
980 void Actor::SetColorBlue( float blue )
984 // mNode is being used in a separate thread; queue a message to set the value & base value
985 SceneGraph::NodePropertyComponentMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
989 void Actor::ColorBy(const Vector4& relativeColor)
993 // mNode is being used in a separate thread; queue a message to set the value & base value
994 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, &mNode->mColor, &AnimatableProperty<Vector4>::BakeRelative, relativeColor );
998 const Vector4& Actor::GetCurrentColor() const
1002 // mNode is being used in a separate thread; copy the value from the previous update
1003 return mNode->GetColor(mStage->GetEventBufferIndex());
1006 return Color::WHITE;
1009 void Actor::SetInheritRotation(bool inherit)
1011 // non animateable so keep local copy
1012 mInheritRotation = inherit;
1015 // mNode is being used in a separate thread; queue a message to set the value
1016 SetInheritRotationMessage( mStage->GetUpdateInterface(), *mNode, inherit );
1020 bool Actor::IsRotationInherited() const
1022 return mInheritRotation;
1025 void Actor::SetColorMode(ColorMode colorMode)
1027 // non animateable so keep local copy
1028 mColorMode = colorMode;
1031 // mNode is being used in a separate thread; queue a message to set the value
1032 SetColorModeMessage( mStage->GetUpdateInterface(), *mNode, colorMode );
1036 ColorMode Actor::GetColorMode() const
1038 // we have cached copy
1042 void Actor::SetSize(float width, float height)
1044 SetSize( Vector2( width, height ) );
1047 void Actor::SetSize(float width, float height, float depth)
1049 SetSize( Vector3( width, height, depth ) );
1052 void Actor::SetSize(const Vector2& size)
1054 Vector3 volume( size );
1055 volume.z = std::min( size.width, size.height );
1059 void Actor::SetSize(const Vector3& size)
1063 // mNode is being used in a separate thread; queue a message to set the value & base value
1064 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, size );
1066 // Notification for derived classes
1069 // Emit signal for application developer
1071 if( !mSetSizeSignalV2.Empty() )
1073 Dali::Actor handle( this );
1074 mSetSizeSignalV2.Emit( handle, size );
1079 void Actor::SetWidth( float width )
1083 // mNode is being used in a separate thread; queue a message to set the value & base value
1084 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeX, width );
1088 void Actor::SetHeight( float height )
1092 // mNode is being used in a separate thread; queue a message to set the value & base value
1093 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeY, height );
1097 void Actor::SetDepth( float depth )
1101 // mNode is being used in a separate thread; queue a message to set the value & base value
1102 SceneGraph::NodePropertyComponentMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::BakeZ, depth );
1106 const Vector3& Actor::GetCurrentSize() const
1110 // mNode is being used in a separate thread; copy the value from the previous update
1111 return mNode->GetSize( mStage->GetEventBufferIndex() );
1114 return Vector3::ZERO;
1117 #ifdef DYNAMICS_SUPPORT
1119 //--------------- Dynamics ---------------
1121 void Actor::DisableDynamics()
1123 if( NULL != mDynamicsData )
1125 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1127 // ensure dynamics object are disconnected from scene
1128 DisconnectDynamics();
1130 // delete joint owned by this actor
1131 while( !mDynamicsData->joints.empty() )
1133 RemoveDynamicsJoint( mDynamicsData->joints.begin()->second );
1136 // delete other joints referencing this actor
1137 while( !mDynamicsData->referencedJoints.empty() )
1139 DynamicsJointPtr joint( *(mDynamicsData->referencedJoints.begin()) );
1140 ActorPtr jointOwner( joint->GetActor( true ) );
1143 jointOwner->RemoveDynamicsJoint( joint );
1147 mDynamicsData->referencedJoints.erase( mDynamicsData->referencedJoints.begin() );
1150 // delete the DynamicsBody object
1151 mDynamicsData->body.Reset();
1153 // Discard Dynamics data structure
1154 delete mDynamicsData;
1155 mDynamicsData = NULL;
1159 DynamicsBodyPtr Actor::GetDynamicsBody() const
1161 DynamicsBodyPtr body;
1163 if( NULL != mDynamicsData )
1165 body = mDynamicsData->body;
1171 DynamicsBodyPtr Actor::EnableDynamics(DynamicsBodyConfigPtr bodyConfig)
1173 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s- (\"%s\")\n", __PRETTY_FUNCTION__, mName.c_str());
1175 if( NULL == mDynamicsData )
1177 mDynamicsData = new DynamicsData( this );
1180 if( !mDynamicsData->body )
1182 mDynamicsData->body = new DynamicsBody(mName, bodyConfig, *this, *(const_cast<SceneGraph::Node*>(mNode)) );
1186 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1189 if( mParent == world->GetRootActor().Get() )
1191 mDynamicsData->body->Connect(*mStage);
1197 return mDynamicsData->body;
1200 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offset )
1202 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1203 return AddDynamicsJoint( attachedActor, offset, ( GetCurrentPosition() + offset ) - attachedActor->GetCurrentPosition() );
1206 DynamicsJointPtr Actor::AddDynamicsJoint( ActorPtr attachedActor, const Vector3& offsetA, const Vector3& offsetB )
1208 DALI_ASSERT_ALWAYS( attachedActor && "'attachedActor' must be initialized!" );
1209 DALI_ASSERT_ALWAYS( this != attachedActor.Get() && "Cannot create a joint to oneself!" );
1211 DynamicsJointPtr joint;
1213 DynamicsWorldPtr world( mStage->GetDynamicsWorld() );
1217 if( NULL != mDynamicsData )
1219 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1221 if( mDynamicsData->joints.end() != it )
1223 // use existing joint
1229 DynamicsBodyPtr bodyA( GetDynamicsBody() );
1230 DynamicsBodyPtr bodyB( attachedActor->GetDynamicsBody() );
1234 bodyA = EnableDynamics( new DynamicsBodyConfig );
1239 bodyB = attachedActor->EnableDynamics( new DynamicsBodyConfig );
1242 joint = new DynamicsJoint(world, bodyA, bodyB, offsetA, offsetB);
1243 mDynamicsData->joints[ attachedActor.Get() ] = joint;
1245 if( OnStage() && attachedActor->OnStage() )
1247 joint->Connect(*mStage);
1250 attachedActor->ReferenceJoint( joint );
1252 attachedActor->OnStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1253 attachedActor->OffStageSignal().Connect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1260 const int Actor::GetNumberOfJoints() const
1262 return static_cast<int>( NULL != mDynamicsData ? mDynamicsData->joints.size() : 0 );
1265 DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
1267 DynamicsJointPtr joint;
1269 if( NULL != mDynamicsData )
1271 if( index >= 0 && index < static_cast<int>(mDynamicsData->joints.size()) )
1273 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
1275 for( int i = 0; i < index; ++i )
1287 DynamicsJointPtr Actor::GetDynamicsJoint( ActorPtr attachedActor ) const
1289 DynamicsJointPtr joint;
1291 if( NULL != mDynamicsData )
1293 DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1295 if( mDynamicsData->joints.end() != it )
1297 // use existing joint
1305 void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
1307 if( NULL != mDynamicsData )
1309 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1310 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1312 for( ; it != endIt; ++it )
1314 if( it->second == joint.Get() )
1316 ActorPtr attachedActor( it->first );
1318 if( OnStage() && attachedActor && attachedActor->OnStage() )
1320 joint->Disconnect(*mStage);
1325 attachedActor->ReleaseJoint( joint );
1326 attachedActor->OnStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOnStage );
1327 attachedActor->OffStageSignal().Disconnect( mDynamicsData->slotDelegate, &Actor::AttachedActorOffStage );
1330 mDynamicsData->joints.erase(it);
1337 void Actor::ReferenceJoint( DynamicsJointPtr joint )
1339 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1341 if( NULL != mDynamicsData )
1343 mDynamicsData->referencedJoints.push_back(joint);
1347 void Actor::ReleaseJoint( DynamicsJointPtr joint )
1349 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1351 if( NULL != mDynamicsData )
1353 DynamicsData::ReferencedJointContainer::iterator it( std::find( mDynamicsData->referencedJoints.begin(), mDynamicsData->referencedJoints.end(), joint ) );
1355 if( it != mDynamicsData->referencedJoints.end() )
1357 mDynamicsData->referencedJoints.erase( it );
1362 void Actor::SetDynamicsRoot(bool flag)
1364 if( mIsDynamicsRoot != flag )
1366 mIsDynamicsRoot = flag;
1368 if( OnStage() && mChildren )
1370 // walk the children connecting or disconnecting any dynamics enabled child from the dynamics simulation
1371 ActorIter end = mChildren->end();
1372 for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
1374 Actor& child = GetImplementation(*iter);
1376 if( child.GetDynamicsBody() )
1378 if( mIsDynamicsRoot )
1380 child.ConnectDynamics();
1384 child.DisconnectDynamics();
1392 bool Actor::IsDynamicsRoot() const
1394 return mIsDynamicsRoot;
1397 void Actor::AttachedActorOnStage( Dali::Actor actor )
1399 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1403 ActorPtr attachedActor( &GetImplementation(actor) );
1405 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1406 if( NULL != mDynamicsData )
1408 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1409 if( mDynamicsData->joints.end() != it )
1411 DynamicsJointPtr joint( it->second );
1412 joint->Connect(*mStage);
1418 void Actor::AttachedActorOffStage( Dali::Actor actor )
1420 DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
1424 ActorPtr attachedActor( &GetImplementation(actor) );
1426 DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
1427 if( NULL != mDynamicsData )
1429 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
1430 if( mDynamicsData->joints.end() != it )
1432 DynamicsJointPtr joint( it->second );
1433 joint->Disconnect(*mStage);
1439 void Actor::ConnectDynamics()
1441 if( NULL != mDynamicsData && mDynamicsData->body )
1443 if( OnStage() && mParent && mParent->IsDynamicsRoot() )
1445 mDynamicsData->body->Connect(*mStage);
1447 // Connect all joints where attachedActor is also on stage
1448 if( !mDynamicsData->joints.empty() )
1450 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1451 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1453 for( ; it != endIt; ++it )
1455 Actor* attachedActor( it->first );
1456 if( NULL != attachedActor && attachedActor->OnStage() )
1458 DynamicsJointPtr joint( it->second );
1460 joint->Connect(*mStage);
1468 void Actor::DisconnectDynamics()
1470 if( NULL != mDynamicsData && mDynamicsData->body )
1474 mDynamicsData->body->Disconnect(*mStage);
1476 // Disconnect all joints
1477 if( !mDynamicsData->joints.empty() )
1479 DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
1480 DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
1482 for( ; it != endIt; ++it )
1484 DynamicsJointPtr joint( it->second );
1486 joint->Disconnect(*mStage);
1493 #endif // DYNAMICS_SUPPORT
1495 void Actor::SetOverlay(bool enable)
1497 // Setting STENCIL will override OVERLAY
1498 if( DrawMode::STENCIL != mDrawMode )
1500 SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL );
1504 bool Actor::IsOverlay() const
1506 return ( DrawMode::OVERLAY == mDrawMode );
1509 void Actor::SetDrawMode( DrawMode::Type drawMode )
1511 // this flag is not animatable so keep the value
1512 mDrawMode = drawMode;
1515 // mNode is being used in a separate thread; queue a message to set the value
1516 SetDrawModeMessage( mStage->GetUpdateInterface(), *mNode, drawMode );
1520 DrawMode::Type Actor::GetDrawMode() const
1525 bool Actor::ScreenToLocal( float& localX,
1528 float screenY ) const
1530 // only valid when on-stage
1533 const RenderTaskList& taskList = mStage->GetRenderTaskList();
1535 Vector2 converted( screenX, screenY );
1537 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1538 const int taskCount = taskList.GetTaskCount();
1539 for( int i = taskCount - 1; i >= 0; --i )
1541 Dali::RenderTask task = taskList.GetTask( i );
1542 if( ScreenToLocal( Dali::GetImplementation( task ), localX, localY, screenX, screenY ) )
1544 // found a task where this conversion was ok so return
1552 bool Actor::ScreenToLocal( RenderTask& renderTask,
1556 float screenY ) const
1558 bool retval = false;
1559 // only valid when on-stage
1562 CameraActor* camera = renderTask.GetCameraActor();
1566 renderTask.GetViewport( viewport );
1568 // need to translate coordinates to render tasks coordinate space
1569 Vector2 converted( screenX, screenY );
1570 if( renderTask.TranslateCoordinates( converted ) )
1572 retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1579 bool Actor::ScreenToLocal( const Matrix& viewMatrix,
1580 const Matrix& projectionMatrix,
1581 const Viewport& viewport,
1585 float screenY ) const
1587 // Early-out if mNode is NULL
1593 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1595 // Calculate the ModelView matrix
1596 Matrix modelView(false/*don't init*/);
1597 // need to use the components as world matrix is only updated for actors that need it
1598 modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1599 Matrix::Multiply(modelView, modelView, viewMatrix);
1601 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
1602 Matrix invertedMvp(false/*don't init*/);
1603 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
1604 bool success = invertedMvp.Invert();
1606 // Convert to GL coordinates
1607 Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
1612 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
1619 success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
1625 if (XyPlaneIntersect(nearPos, farPos, local))
1627 Vector3 size = GetCurrentSize();
1628 localX = local.x + size.x * 0.5f;
1629 localY = local.y + size.y * 0.5f;
1640 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
1643 http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
1645 Mathematical Formulation
1647 Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
1649 ( p - c ) dot ( p - c ) = r^2
1651 Given a ray with a point of origin 'o', and a direction vector 'd':
1653 ray(t) = o + td, t >= 0
1655 we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p'
1657 (o + td - c ) dot ( o + td - c ) = r^2
1659 To solve for t we first expand the above into a more recognisable quadratic equation form
1661 ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
1670 B = 2( o - c ) dot d
1671 C = ( o - c ) dot ( o - c ) - r^2
1673 which can be solved using a standard quadratic formula.
1675 Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
1677 Practical Simplification
1679 In a renderer, we often differentiate between world space and object space. In the object space
1680 of a sphere it is centred at origin, meaning that if we first transform the ray from world space
1681 into object space, the mathematical solution presented above can be simplified significantly.
1683 If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
1687 and we can find the t at which the (transformed) ray intersects the sphere by
1689 ( o + td ) dot ( o + td ) = r^2
1691 According to the reasoning above, we expand the above quadratic equation into the general form
1695 which now has coefficients:
1702 // Early out if mNode is NULL
1708 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1710 // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
1711 const Vector3& translation( mNode->GetWorldPosition( bufferIndex ) );
1712 Vector3 rayOriginLocal(rayOrigin.x - translation.x,
1713 rayOrigin.y - translation.y,
1714 rayOrigin.z - translation.z);
1716 // Compute the radius is not needed, square radius it's enough.
1717 const Vector3& size( mNode->GetSize( bufferIndex ) );
1719 // Scale the sphere.
1720 const Vector3& scale( mNode->GetWorldScale( bufferIndex ) );
1722 const float width = size.width * scale.width;
1723 const float height = size.height * scale.height;
1725 float squareSphereRadius = 0.5f * ( width * width + height * height );
1727 float a = rayDir.Dot( rayDir ); // a
1728 float b2 = rayDir.Dot( rayOriginLocal ); // b/2
1729 float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c
1731 return ( b2*b2 - a*c ) >= 0.f;
1734 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
1741 BufferIndex bufferIndex( mStage->GetEventBufferIndex() );
1743 // Transforms the ray to the local reference system.
1745 // Calculate the inverse of Model matrix
1746 Matrix invModelMatrix(false/*don't init*/);
1747 // need to use the components as world matrix is only updated for actors that need it
1748 invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldRotation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
1750 Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
1751 Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
1753 // Test with the actor's XY plane (Normal = 0 0 1 1).
1755 float a = -rayOriginLocal.z;
1756 float b = rayDirLocal.z;
1758 if( fabsf( b ) > Math::MACHINE_EPSILON_1 )
1760 // Ray travels distance * rayDirLocal to intersect with plane.
1763 const Vector3& size = mNode->GetSize( bufferIndex );
1765 hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
1766 hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
1768 // Test with the actor's geometry.
1769 hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y );
1776 void Actor::SetLeaveRequired(bool required)
1778 mLeaveRequired = required;
1781 bool Actor::GetLeaveRequired() const
1783 return mLeaveRequired;
1786 void Actor::SetKeyboardFocusable( bool focusable )
1788 mKeyboardFocusable = focusable;
1791 bool Actor::IsKeyboardFocusable() const
1793 return mKeyboardFocusable;
1796 bool Actor::GetTouchRequired() const
1798 return !mTouchedSignalV2.Empty() || mDerivedRequiresTouch;
1801 bool Actor::GetMouseWheelEventRequired() const
1803 return !mMouseWheelEventSignalV2.Empty() || mDerivedRequiresMouseWheelEvent;
1806 bool Actor::IsHittable() const
1808 return IsSensitive() &&
1810 ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
1814 ActorGestureData& Actor::GetGestureData()
1816 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1817 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1818 if ( NULL == mGestureData )
1820 mGestureData = new ActorGestureData;
1822 return *mGestureData;
1825 bool Actor::IsGestureRequred( Gesture::Type type ) const
1827 return mGestureData && mGestureData->IsGestureRequred( type );
1830 bool Actor::EmitTouchEventSignal(const TouchEvent& event)
1832 bool consumed = false;
1834 if ( !mTouchedSignalV2.Empty() )
1836 Dali::Actor handle( this );
1837 consumed = mTouchedSignalV2.Emit( handle, event );
1842 // Notification for derived classes
1843 consumed = OnTouchEvent( event );
1849 bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
1851 bool consumed = false;
1853 if ( !mMouseWheelEventSignalV2.Empty() )
1855 Dali::Actor handle( this );
1856 consumed = mMouseWheelEventSignalV2.Emit( handle, event );
1861 // Notification for derived classes
1862 consumed = OnMouseWheelEvent(event);
1868 Dali::Actor::TouchSignalV2& Actor::TouchedSignal()
1870 return mTouchedSignalV2;
1873 Dali::Actor::MouseWheelEventSignalV2& Actor::MouseWheelEventSignal()
1875 return mMouseWheelEventSignalV2;
1878 Dali::Actor::SetSizeSignalV2& Actor::SetSizeSignal()
1880 return mSetSizeSignalV2;
1883 Dali::Actor::OnStageSignalV2& Actor::OnStageSignal()
1885 return mOnStageSignalV2;
1888 Dali::Actor::OffStageSignalV2& Actor::OffStageSignal()
1890 return mOffStageSignalV2;
1893 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1895 bool connected( true );
1896 Actor* actor = dynamic_cast<Actor*>(object);
1898 if(Dali::Actor::SIGNAL_TOUCHED == signalName)
1900 actor->TouchedSignal().Connect( tracker, functor );
1902 else if(Dali::Actor::SIGNAL_MOUSE_WHEEL_EVENT == signalName)
1904 actor->MouseWheelEventSignal().Connect( tracker, functor );
1906 else if(Dali::Actor::SIGNAL_SET_SIZE == signalName)
1908 actor->SetSizeSignal().Connect( tracker, functor );
1910 else if(Dali::Actor::SIGNAL_ON_STAGE == signalName)
1912 actor->OnStageSignal().Connect( tracker, functor );
1914 else if(Dali::Actor::SIGNAL_OFF_STAGE == signalName)
1916 actor->OffStageSignal().Connect( tracker, functor );
1920 // signalName does not match any signal
1927 Actor::Actor( DerivedType derivedType )
1932 mParentOrigin( NULL ),
1933 mAnchorPoint( NULL ),
1934 #ifdef DYNAMICS_SUPPORT
1935 mDynamicsData( NULL ),
1937 mGestureData( NULL ),
1940 mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
1941 mIsRoot( ROOT_LAYER == derivedType ),
1942 mIsRenderable( RENDERABLE == derivedType ),
1943 mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1944 mIsOnStage( false ),
1945 mIsDynamicsRoot(false),
1947 mLeaveRequired( false ),
1948 mKeyboardFocusable( false ),
1949 mDerivedRequiresTouch( false ),
1950 mDerivedRequiresMouseWheelEvent( false ),
1951 mOnStageSignalled( false ),
1952 mInheritRotation( true ),
1953 mInheritScale( true ),
1954 mDrawMode( DrawMode::NORMAL ),
1955 mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
1956 mColorMode( Node::DEFAULT_COLOR_MODE )
1960 void Actor::Initialize()
1962 mStage = Stage::GetCurrent();
1965 SceneGraph::Node* node = CreateNode();
1967 AddNodeMessage( mStage->GetUpdateManager(), *node ); // Pass ownership to scene-graph
1968 mNode = node; // Keep raw-pointer to Node
1970 if(!mDefaultPropertyLookup)
1972 mDefaultPropertyLookup = new DefaultPropertyLookup();
1974 for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
1976 (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_DETAILS[i].name] = i;
1987 // Remove mParent pointers from children even if we're destroying core,
1988 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1991 ActorConstIter endIter = mChildren->end();
1992 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
1994 Actor& actor = GetImplementation( *iter );
1995 actor.SetParent( NULL );
2000 // Guard to allow handle destruction after Core has been destroyed
2001 if( Stage::IsInstalled() )
2005 DestroyNodeMessage( mStage->GetUpdateManager(), *mNode );
2006 mNode = NULL; // Node is about to be destroyed
2012 #ifdef DYNAMICS_SUPPORT
2014 delete mDynamicsData;
2017 // Cleanup optional gesture data
2018 delete mGestureData;
2020 // Cleanup optional parent origin and anchor
2021 delete mParentOrigin;
2022 delete mAnchorPoint;
2025 void Actor::ConnectToStage( Stage& stage )
2027 // This container is used instead of walking the Actor hierachy.
2028 // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks.
2029 ActorContainer connectionList;
2031 // This stage is atomic i.e. not interrupted by user callbacks
2032 RecursiveConnectToStage( stage, connectionList );
2034 // Notify applications about the newly connected actors.
2035 const ActorIter endIter = connectionList.end();
2036 for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
2038 Actor& actor = GetImplementation(*iter);
2039 actor.NotifyStageConnection();
2043 void Actor::RecursiveConnectToStage( Stage& stage, ActorContainer& connectionList )
2045 DALI_ASSERT_ALWAYS( !OnStage() );
2049 ConnectToSceneGraph();
2051 // Notification for internal derived classes
2052 OnStageConnectionInternal();
2054 // This stage is atomic; avoid emitting callbacks until all Actors are connected
2055 connectionList.push_back( Dali::Actor(this) );
2057 // Recursively connect children
2060 ActorConstIter endIter = mChildren->end();
2061 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2063 Actor& actor = GetImplementation( *iter );
2064 actor.RecursiveConnectToStage( stage, connectionList );
2070 * This method is called when the Actor is connected to the Stage.
2071 * The parent must have added its Node to the scene-graph.
2072 * The child must connect its Node to the parent's Node.
2073 * This is resursive; the child calls ConnectToStage() for its children.
2075 void Actor::ConnectToSceneGraph()
2077 DALI_ASSERT_DEBUG( mNode != NULL);
2078 DALI_ASSERT_DEBUG( mParent != NULL);
2079 DALI_ASSERT_DEBUG( mParent->mNode != NULL );
2083 // Reparent Node in next Update
2084 ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
2087 // Notify attachment
2090 mAttachment->Connect();
2093 #ifdef DYNAMICS_SUPPORT
2095 if( NULL != mDynamicsData )
2101 // Notification for ProxyObject::Observers
2105 void Actor::NotifyStageConnection()
2107 // Actors can be removed (in a callback), before the on-stage stage is reported.
2108 // The actor may also have been reparented, in which case mOnStageSignalled will be true.
2109 if ( OnStage() && !mOnStageSignalled )
2111 // Notification for external (CustomActor) derived classes
2112 OnStageConnectionExternal();
2114 if ( !mOnStageSignalV2.Empty() )
2116 Dali::Actor handle( this );
2117 mOnStageSignalV2.Emit( handle );
2120 // Guard against Remove during callbacks
2123 mOnStageSignalled = true; // signal required next time Actor is removed
2128 void Actor::DisconnectFromStage()
2130 // This container is used instead of walking the Actor hierachy.
2131 // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
2132 ActorContainer disconnectionList;
2134 // This stage is atomic i.e. not interrupted by user callbacks
2135 RecursiveDisconnectFromStage( disconnectionList );
2137 // Notify applications about the newly disconnected actors.
2138 const ActorIter endIter = disconnectionList.end();
2139 for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
2141 Actor& actor = GetImplementation(*iter);
2142 actor.NotifyStageDisconnection();
2146 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
2148 DALI_ASSERT_ALWAYS( OnStage() );
2150 // Recursively disconnect children
2153 ActorConstIter endIter = mChildren->end();
2154 for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
2156 Actor& actor = GetImplementation( *iter );
2157 actor.RecursiveDisconnectFromStage( disconnectionList );
2161 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
2162 disconnectionList.push_back( Dali::Actor(this) );
2164 // Notification for internal derived classes
2165 OnStageDisconnectionInternal();
2167 DisconnectFromSceneGraph();
2173 * This method is called by an actor or its parent, before a node removal message is sent.
2174 * This is recursive; the child calls DisconnectFromStage() for its children.
2176 void Actor::DisconnectFromSceneGraph()
2178 // Notification for ProxyObject::Observers
2179 OnSceneObjectRemove();
2181 // Notify attachment
2184 mAttachment->Disconnect();
2187 #ifdef DYNAMICS_SUPPORT
2189 if( NULL != mDynamicsData )
2191 DisconnectDynamics();
2196 void Actor::NotifyStageDisconnection()
2198 // Actors can be added (in a callback), before the off-stage state is reported.
2199 // Also if the actor was added & removed before mOnStageSignalled was set, then we don't notify here.
2200 // only do this step if there is a stage, i.e. Core is not being shut down
2201 if ( Stage::IsInstalled() && !OnStage() && mOnStageSignalled )
2203 // Notification for external (CustomeActor) derived classes
2204 OnStageDisconnectionExternal();
2206 if( !mOffStageSignalV2.Empty() )
2208 Dali::Actor handle( this );
2209 mOffStageSignalV2.Emit( handle );
2212 // Guard against Add during callbacks
2215 mOnStageSignalled = false; // signal required next time Actor is added
2220 bool Actor::IsNodeConnected() const
2222 bool connected( false );
2227 if( mNode->IsRoot() || mNode->GetParent() )
2236 bool Actor::IsSceneObjectRemovable() const
2241 unsigned int Actor::GetDefaultPropertyCount() const
2243 return DEFAULT_PROPERTY_COUNT;
2246 void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
2248 indices.reserve( DEFAULT_PROPERTY_COUNT );
2250 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
2252 indices.push_back( i );
2256 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
2258 if( index < DEFAULT_PROPERTY_COUNT )
2260 return DEFAULT_PROPERTY_DETAILS[index].name;
2264 // index out of range..return empty string
2265 return String::EMPTY;
2269 Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
2271 Property::Index index = Property::INVALID_INDEX;
2273 DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
2275 // Look for name in default properties
2276 DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
2277 if ( mDefaultPropertyLookup->end() != result )
2279 index = result->second;
2285 bool Actor::IsDefaultPropertyWritable(Property::Index index) const
2287 if( index < DEFAULT_PROPERTY_COUNT )
2289 return DEFAULT_PROPERTY_DETAILS[index].writable;
2297 bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
2299 if( index < DEFAULT_PROPERTY_COUNT )
2301 return DEFAULT_PROPERTY_DETAILS[index].animatable;
2309 bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
2311 if( index < DEFAULT_PROPERTY_COUNT )
2313 return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
2321 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
2323 if( index < DEFAULT_PROPERTY_COUNT )
2325 return DEFAULT_PROPERTY_DETAILS[index].type;
2329 // index out of range...return Property::NONE
2330 return Property::NONE;
2334 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
2338 case Dali::Actor::PARENT_ORIGIN:
2340 SetParentOrigin( property.Get<Vector3>() );
2344 case Dali::Actor::PARENT_ORIGIN_X:
2346 SetParentOriginX( property.Get<float>() );
2350 case Dali::Actor::PARENT_ORIGIN_Y:
2352 SetParentOriginY( property.Get<float>() );
2356 case Dali::Actor::PARENT_ORIGIN_Z:
2358 SetParentOriginZ( property.Get<float>() );
2362 case Dali::Actor::ANCHOR_POINT:
2364 SetAnchorPoint( property.Get<Vector3>() );
2368 case Dali::Actor::ANCHOR_POINT_X:
2370 SetAnchorPointX( property.Get<float>() );
2374 case Dali::Actor::ANCHOR_POINT_Y:
2376 SetAnchorPointY( property.Get<float>() );
2380 case Dali::Actor::ANCHOR_POINT_Z:
2382 SetAnchorPointZ( property.Get<float>() );
2386 case Dali::Actor::SIZE:
2388 SetSize( property.Get<Vector3>() );
2392 case Dali::Actor::SIZE_WIDTH:
2394 SetWidth( property.Get<float>() );
2398 case Dali::Actor::SIZE_HEIGHT:
2400 SetHeight( property.Get<float>() );
2404 case Dali::Actor::SIZE_DEPTH:
2406 SetDepth( property.Get<float>() );
2410 case Dali::Actor::POSITION:
2412 SetPosition( property.Get<Vector3>() );
2416 case Dali::Actor::POSITION_X:
2418 SetX( property.Get<float>() );
2422 case Dali::Actor::POSITION_Y:
2424 SetY( property.Get<float>() );
2428 case Dali::Actor::POSITION_Z:
2430 SetZ( property.Get<float>() );
2434 case Dali::Actor::ROTATION:
2436 SetRotation( property.Get<Quaternion>() );
2440 case Dali::Actor::SCALE:
2442 SetScale( property.Get<Vector3>() );
2446 case Dali::Actor::SCALE_X:
2448 SetScaleX( property.Get<float>() );
2452 case Dali::Actor::SCALE_Y:
2454 SetScaleY( property.Get<float>() );
2458 case Dali::Actor::SCALE_Z:
2460 SetScaleZ( property.Get<float>() );
2464 case Dali::Actor::VISIBLE:
2466 SetVisible( property.Get<bool>() );
2470 case Dali::Actor::COLOR:
2472 SetColor( property.Get<Vector4>() );
2476 case Dali::Actor::COLOR_RED:
2478 SetColorRed( property.Get<float>() );
2482 case Dali::Actor::COLOR_GREEN:
2484 SetColorGreen( property.Get<float>() );
2488 case Dali::Actor::COLOR_BLUE:
2490 SetColorBlue( property.Get<float>() );
2494 case Dali::Actor::COLOR_ALPHA:
2496 SetOpacity( property.Get<float>() );
2500 case Dali::Actor::NAME:
2502 SetName( property.Get<std::string>() );
2506 case Dali::Actor::SENSITIVE:
2508 SetSensitive( property.Get<bool>() );
2512 case Dali::Actor::LEAVE_REQUIRED:
2514 SetLeaveRequired( property.Get<bool>() );
2518 case Dali::Actor::INHERIT_ROTATION:
2520 SetInheritRotation( property.Get<bool>() );
2524 case Dali::Actor::INHERIT_SCALE:
2526 SetInheritScale( property.Get<bool>() );
2530 case Dali::Actor::COLOR_MODE:
2532 SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
2536 case Dali::Actor::POSITION_INHERITANCE:
2538 SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
2542 case Dali::Actor::DRAW_MODE:
2544 SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
2550 DALI_ASSERT_ALWAYS(false && "Actor::Property is out of bounds"); // should not come here
2556 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
2558 // TODO: This should be deprecated
2559 OnPropertySet(index, value);
2561 if(entry.IsAnimatable())
2563 // TODO: ADD MATRIX & MATRIX3 types
2565 switch ( entry.type )
2567 case Property::BOOLEAN:
2569 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
2570 DALI_ASSERT_DEBUG( NULL != property );
2572 // property is being used in a separate thread; queue a message to set the property
2573 SceneGraph::NodePropertyMessage<bool>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<bool>::Bake, value.Get<bool>() );
2578 case Property::FLOAT:
2580 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
2581 DALI_ASSERT_DEBUG( NULL != property );
2583 // property is being used in a separate thread; queue a message to set the property
2584 SceneGraph::NodePropertyMessage<float>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<float>::Bake, value.Get<float>() );
2589 case Property::INTEGER:
2591 AnimatableProperty<int>* property = dynamic_cast< AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
2592 DALI_ASSERT_DEBUG( NULL != property );
2594 // property is being used in a separate thread; queue a message to set the property
2595 SceneGraph::NodePropertyMessage<int>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<int>::Bake, value.Get<int>() );
2600 case Property::VECTOR2:
2602 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
2603 DALI_ASSERT_DEBUG( NULL != property );
2605 // property is being used in a separate thread; queue a message to set the property
2606 SceneGraph::NodePropertyMessage<Vector2>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
2611 case Property::VECTOR3:
2613 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
2614 DALI_ASSERT_DEBUG( NULL != property );
2616 // property is being used in a separate thread; queue a message to set the property
2617 SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
2622 case Property::VECTOR4:
2624 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
2625 DALI_ASSERT_DEBUG( NULL != property );
2627 // property is being used in a separate thread; queue a message to set the property
2628 SceneGraph::NodePropertyMessage<Vector4>::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
2633 case Property::ROTATION:
2635 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
2636 DALI_ASSERT_DEBUG( NULL != property );
2638 // property is being used in a separate thread; queue a message to set the property
2639 SceneGraph::NodePropertyMessage<Quaternion>::Send( mStage->GetUpdateManager(), mNode, property,&AnimatableProperty<Quaternion>::Bake, value.Get<Quaternion>() );
2646 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
2653 Property::Value Actor::GetDefaultProperty(Property::Index index) const
2655 Property::Value value;
2659 case Dali::Actor::PARENT_ORIGIN:
2661 value = GetCurrentParentOrigin();
2665 case Dali::Actor::PARENT_ORIGIN_X:
2667 value = GetCurrentParentOrigin().x;
2671 case Dali::Actor::PARENT_ORIGIN_Y:
2673 value = GetCurrentParentOrigin().y;
2677 case Dali::Actor::PARENT_ORIGIN_Z:
2679 value = GetCurrentParentOrigin().z;
2683 case Dali::Actor::ANCHOR_POINT:
2685 value = GetCurrentAnchorPoint();
2689 case Dali::Actor::ANCHOR_POINT_X:
2691 value = GetCurrentAnchorPoint().x;
2695 case Dali::Actor::ANCHOR_POINT_Y:
2697 value = GetCurrentAnchorPoint().y;
2701 case Dali::Actor::ANCHOR_POINT_Z:
2703 value = GetCurrentAnchorPoint().z;
2707 case Dali::Actor::SIZE:
2709 value = GetCurrentSize();
2713 case Dali::Actor::SIZE_WIDTH:
2715 value = GetCurrentSize().width;
2719 case Dali::Actor::SIZE_HEIGHT:
2721 value = GetCurrentSize().height;
2725 case Dali::Actor::SIZE_DEPTH:
2727 value = GetCurrentSize().depth;
2731 case Dali::Actor::POSITION:
2733 value = GetCurrentPosition();
2737 case Dali::Actor::POSITION_X:
2739 value = GetCurrentPosition().x;
2743 case Dali::Actor::POSITION_Y:
2745 value = GetCurrentPosition().y;
2749 case Dali::Actor::POSITION_Z:
2751 value = GetCurrentPosition().z;
2755 case Dali::Actor::WORLD_POSITION:
2757 value = GetCurrentWorldPosition();
2761 case Dali::Actor::WORLD_POSITION_X:
2763 value = GetCurrentWorldPosition().x;
2767 case Dali::Actor::WORLD_POSITION_Y:
2769 value = GetCurrentWorldPosition().y;
2773 case Dali::Actor::WORLD_POSITION_Z:
2775 value = GetCurrentWorldPosition().z;
2779 case Dali::Actor::ROTATION:
2781 value = GetCurrentRotation();
2785 case Dali::Actor::WORLD_ROTATION:
2787 value = GetCurrentWorldRotation();
2791 case Dali::Actor::SCALE:
2793 value = GetCurrentScale();
2797 case Dali::Actor::SCALE_X:
2799 value = GetCurrentScale().x;
2803 case Dali::Actor::SCALE_Y:
2805 value = GetCurrentScale().y;
2809 case Dali::Actor::SCALE_Z:
2811 value = GetCurrentScale().z;
2815 case Dali::Actor::WORLD_SCALE:
2817 value = GetCurrentWorldScale();
2821 case Dali::Actor::VISIBLE:
2823 value = IsVisible();
2827 case Dali::Actor::COLOR:
2829 value = GetCurrentColor();
2833 case Dali::Actor::COLOR_RED:
2835 value = GetCurrentColor().r;
2839 case Dali::Actor::COLOR_GREEN:
2841 value = GetCurrentColor().g;
2845 case Dali::Actor::COLOR_BLUE:
2847 value = GetCurrentColor().b;
2851 case Dali::Actor::COLOR_ALPHA:
2853 value = GetCurrentColor().a;
2857 case Dali::Actor::WORLD_COLOR:
2859 value = GetCurrentWorldColor();
2863 case Dali::Actor::WORLD_MATRIX:
2865 value = GetCurrentWorldMatrix();
2869 case Dali::Actor::NAME:
2875 case Dali::Actor::SENSITIVE:
2877 value = IsSensitive();
2881 case Dali::Actor::LEAVE_REQUIRED:
2883 value = GetLeaveRequired();
2887 case Dali::Actor::INHERIT_ROTATION:
2889 value = IsRotationInherited();
2893 case Dali::Actor::INHERIT_SCALE:
2895 value = IsScaleInherited();
2899 case Dali::Actor::COLOR_MODE:
2901 value = Scripting::GetColorMode( GetColorMode() );
2905 case Dali::Actor::POSITION_INHERITANCE:
2907 value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() );
2911 case Dali::Actor::DRAW_MODE:
2913 value = Scripting::GetDrawMode( GetDrawMode() );
2919 DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
2927 void Actor::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
2931 // mNode is being used in a separate thread; queue a message to add the property
2932 InstallCustomPropertyMessage( mStage->GetUpdateInterface(), *mNode, newProperty ); // Message takes ownership
2936 const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
2938 // This method should only return an object connected to the scene-graph
2939 return OnStage() ? mNode : NULL;
2942 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
2944 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
2946 const PropertyBase* property( NULL );
2948 // This method should only return a property of an object connected to the scene-graph
2954 if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
2956 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
2958 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" );
2960 property = dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
2962 else if( NULL != mNode )
2966 case Dali::Actor::SIZE:
2967 property = &mNode->mSize;
2970 case Dali::Actor::SIZE_WIDTH:
2971 property = &mNode->mSize;
2974 case Dali::Actor::SIZE_HEIGHT:
2975 property = &mNode->mSize;
2978 case Dali::Actor::SIZE_DEPTH:
2979 property = &mNode->mSize;
2982 case Dali::Actor::POSITION:
2983 property = &mNode->mPosition;
2986 case Dali::Actor::POSITION_X:
2987 property = &mNode->mPosition;
2990 case Dali::Actor::POSITION_Y:
2991 property = &mNode->mPosition;
2994 case Dali::Actor::POSITION_Z:
2995 property = &mNode->mPosition;
2998 case Dali::Actor::ROTATION:
2999 property = &mNode->mRotation;
3002 case Dali::Actor::SCALE:
3003 property = &mNode->mScale;
3006 case Dali::Actor::SCALE_X:
3007 property = &mNode->mScale;
3010 case Dali::Actor::SCALE_Y:
3011 property = &mNode->mScale;
3014 case Dali::Actor::SCALE_Z:
3015 property = &mNode->mScale;
3018 case Dali::Actor::VISIBLE:
3019 property = &mNode->mVisible;
3022 case Dali::Actor::COLOR:
3023 property = &mNode->mColor;
3026 case Dali::Actor::COLOR_RED:
3027 property = &mNode->mColor;
3030 case Dali::Actor::COLOR_GREEN:
3031 property = &mNode->mColor;
3034 case Dali::Actor::COLOR_BLUE:
3035 property = &mNode->mColor;
3038 case Dali::Actor::COLOR_ALPHA:
3039 property = &mNode->mColor;
3050 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
3052 const PropertyInputImpl* property( NULL );
3054 // This method should only return a property of an object connected to the scene-graph
3060 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
3062 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
3064 DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "property index is invalid" );
3066 property = entry->second.GetSceneGraphProperty();
3068 else if( NULL != mNode )
3072 case Dali::Actor::PARENT_ORIGIN:
3073 property = &mNode->mParentOrigin;
3076 case Dali::Actor::PARENT_ORIGIN_X:
3077 property = &mNode->mParentOrigin;
3080 case Dali::Actor::PARENT_ORIGIN_Y:
3081 property = &mNode->mParentOrigin;
3084 case Dali::Actor::PARENT_ORIGIN_Z:
3085 property = &mNode->mParentOrigin;
3088 case Dali::Actor::ANCHOR_POINT:
3089 property = &mNode->mAnchorPoint;
3092 case Dali::Actor::ANCHOR_POINT_X:
3093 property = &mNode->mAnchorPoint;
3096 case Dali::Actor::ANCHOR_POINT_Y:
3097 property = &mNode->mAnchorPoint;
3100 case Dali::Actor::ANCHOR_POINT_Z:
3101 property = &mNode->mAnchorPoint;
3104 case Dali::Actor::SIZE:
3105 property = &mNode->mSize;
3108 case Dali::Actor::SIZE_WIDTH:
3109 property = &mNode->mSize;
3112 case Dali::Actor::SIZE_HEIGHT:
3113 property = &mNode->mSize;
3116 case Dali::Actor::SIZE_DEPTH:
3117 property = &mNode->mSize;
3120 case Dali::Actor::POSITION:
3121 property = &mNode->mPosition;
3124 case Dali::Actor::POSITION_X:
3125 property = &mNode->mPosition;
3128 case Dali::Actor::POSITION_Y:
3129 property = &mNode->mPosition;
3132 case Dali::Actor::POSITION_Z:
3133 property = &mNode->mPosition;
3136 case Dali::Actor::WORLD_POSITION:
3137 property = &mNode->mWorldPosition;
3140 case Dali::Actor::WORLD_POSITION_X:
3141 property = &mNode->mWorldPosition;
3144 case Dali::Actor::WORLD_POSITION_Y:
3145 property = &mNode->mWorldPosition;
3148 case Dali::Actor::WORLD_POSITION_Z:
3149 property = &mNode->mWorldPosition;
3152 case Dali::Actor::ROTATION:
3153 property = &mNode->mRotation;
3156 case Dali::Actor::WORLD_ROTATION:
3157 property = &mNode->mWorldRotation;
3160 case Dali::Actor::SCALE:
3161 property = &mNode->mScale;
3164 case Dali::Actor::SCALE_X:
3165 property = &mNode->mScale;
3168 case Dali::Actor::SCALE_Y:
3169 property = &mNode->mScale;
3172 case Dali::Actor::SCALE_Z:
3173 property = &mNode->mScale;
3176 case Dali::Actor::WORLD_SCALE:
3177 property = &mNode->mWorldScale;
3180 case Dali::Actor::VISIBLE:
3181 property = &mNode->mVisible;
3184 case Dali::Actor::COLOR:
3185 property = &mNode->mColor;
3188 case Dali::Actor::COLOR_RED:
3189 property = &mNode->mColor;
3192 case Dali::Actor::COLOR_GREEN:
3193 property = &mNode->mColor;
3196 case Dali::Actor::COLOR_BLUE:
3197 property = &mNode->mColor;
3200 case Dali::Actor::COLOR_ALPHA:
3201 property = &mNode->mColor;
3204 case Dali::Actor::WORLD_COLOR:
3205 property = &mNode->mWorldColor;
3208 case Dali::Actor::WORLD_MATRIX:
3209 property = &mNode->mWorldMatrix;
3220 int Actor::GetPropertyComponentIndex( Property::Index index ) const
3222 int componentIndex( Property::INVALID_COMPONENT_INDEX );
3226 case Dali::Actor::PARENT_ORIGIN_X:
3227 case Dali::Actor::ANCHOR_POINT_X:
3228 case Dali::Actor::SIZE_WIDTH:
3229 case Dali::Actor::POSITION_X:
3230 case Dali::Actor::SCALE_X:
3231 case Dali::Actor::COLOR_RED:
3232 case Dali::Actor::WORLD_POSITION_X:
3238 case Dali::Actor::PARENT_ORIGIN_Y:
3239 case Dali::Actor::ANCHOR_POINT_Y:
3240 case Dali::Actor::SIZE_HEIGHT:
3241 case Dali::Actor::POSITION_Y:
3242 case Dali::Actor::SCALE_Y:
3243 case Dali::Actor::COLOR_GREEN:
3244 case Dali::Actor::WORLD_POSITION_Y:
3250 case Dali::Actor::PARENT_ORIGIN_Z:
3251 case Dali::Actor::ANCHOR_POINT_Z:
3252 case Dali::Actor::SIZE_DEPTH:
3253 case Dali::Actor::POSITION_Z:
3254 case Dali::Actor::SCALE_Z:
3255 case Dali::Actor::COLOR_BLUE:
3256 case Dali::Actor::WORLD_POSITION_Z:
3262 case Dali::Actor::COLOR_ALPHA:
3275 return componentIndex;
3278 void Actor::SetParent(Actor* parent)
3282 DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
3286 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3289 StagePtr stage = parent->mStage;
3291 // Instruct each actor to create a corresponding node in the scene graph
3292 ConnectToStage(*stage);
3295 else // parent being set to NULL
3297 DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" );
3301 if ( Stage::IsInstalled() && // Don't emit signals or send messages during Core destruction
3304 DALI_ASSERT_ALWAYS(mNode != NULL);
3308 // Disconnect the Node & its children from the scene-graph.
3309 DisconnectNodeMessage( mStage->GetUpdateManager(), *mNode );
3312 // Instruct each actor to discard pointers to the scene-graph
3313 DisconnectFromStage();
3318 SceneGraph::Node* Actor::CreateNode() const
3323 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
3326 Actor* actor = dynamic_cast<Actor*>(object);
3330 if(Dali::Actor::ACTION_SHOW == actionName)
3332 actor->SetVisible(true);
3335 else if(Dali::Actor::ACTION_HIDE == actionName)
3337 actor->SetVisible(false);
3345 } // namespace Internal