Clean up the code to build successfully on macOS
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/actors/actor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cmath>
23 #include <algorithm>
24 #include <cfloat>
25
26 // INTERNAL INCLUDES
27 #include <dali/devel-api/actors/layer-devel.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/common/constants.h>
30 #include <dali/public-api/math/vector2.h>
31 #include <dali/public-api/math/vector3.h>
32 #include <dali/public-api/math/radian.h>
33 #include <dali/public-api/object/type-registry.h>
34 #include <dali/devel-api/actors/actor-devel.h>
35 #include <dali/internal/event/actors/actor-property-handler.h>
36 #include <dali/internal/event/actors/actor-relayouter.h>
37 #include <dali/internal/event/common/event-thread-services.h>
38 #include <dali/internal/event/render-tasks/render-task-impl.h>
39 #include <dali/internal/event/actors/camera-actor-impl.h>
40 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
41 #include <dali/internal/event/common/property-helper.h>
42 #include <dali/internal/event/common/stage-impl.h>
43 #include <dali/internal/event/common/type-info-impl.h>
44 #include <dali/internal/event/common/scene-impl.h>
45 #include <dali/internal/event/common/thread-local-storage.h>
46 #include <dali/internal/event/common/projection.h>
47 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
48 #include <dali/internal/update/nodes/node-messages.h>
49 #include <dali/internal/event/events/actor-gesture-data.h>
50 #include <dali/integration-api/debug.h>
51
52 using Dali::Internal::SceneGraph::Node;
53 using Dali::Internal::SceneGraph::AnimatableProperty;
54 using Dali::Internal::SceneGraph::PropertyBase;
55
56 #if defined(DEBUG_ENABLED)
57 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
58 Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
59 #endif
60
61 namespace Dali
62 {
63
64 namespace Internal
65 {
66
67 namespace // unnamed namespace
68 {
69
70 // Properties
71
72 /**
73  * We want to discourage the use of property strings (minimize string comparisons),
74  * particularly for the default properties.
75  *              Name                  Type   writable animatable constraint-input  enum for index-checking
76  */
77 DALI_PROPERTY_TABLE_BEGIN
78 DALI_PROPERTY( "parentOrigin",              VECTOR3,  true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN )
79 DALI_PROPERTY( "parentOriginX",             FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_X )
80 DALI_PROPERTY( "parentOriginY",             FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_Y )
81 DALI_PROPERTY( "parentOriginZ",             FLOAT,    true,  false, true,  Dali::Actor::Property::PARENT_ORIGIN_Z )
82 DALI_PROPERTY( "anchorPoint",               VECTOR3,  true,  false, true,  Dali::Actor::Property::ANCHOR_POINT )
83 DALI_PROPERTY( "anchorPointX",              FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_X )
84 DALI_PROPERTY( "anchorPointY",              FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_Y )
85 DALI_PROPERTY( "anchorPointZ",              FLOAT,    true,  false, true,  Dali::Actor::Property::ANCHOR_POINT_Z )
86 DALI_PROPERTY( "size",                      VECTOR3,  true,  true,  true,  Dali::Actor::Property::SIZE )
87 DALI_PROPERTY( "sizeWidth",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_WIDTH )
88 DALI_PROPERTY( "sizeHeight",                FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_HEIGHT )
89 DALI_PROPERTY( "sizeDepth",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::SIZE_DEPTH )
90 DALI_PROPERTY( "position",                  VECTOR3,  true,  true,  true,  Dali::Actor::Property::POSITION )
91 DALI_PROPERTY( "positionX",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_X )
92 DALI_PROPERTY( "positionY",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_Y )
93 DALI_PROPERTY( "positionZ",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::POSITION_Z )
94 DALI_PROPERTY( "worldPosition",             VECTOR3,  false, false, true,  Dali::Actor::Property::WORLD_POSITION )
95 DALI_PROPERTY( "worldPositionX",            FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_X )
96 DALI_PROPERTY( "worldPositionY",            FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_Y )
97 DALI_PROPERTY( "worldPositionZ",            FLOAT,    false, false, true,  Dali::Actor::Property::WORLD_POSITION_Z )
98 DALI_PROPERTY( "orientation",               ROTATION, true,  true,  true,  Dali::Actor::Property::ORIENTATION )
99 DALI_PROPERTY( "worldOrientation",          ROTATION, false, false, true,  Dali::Actor::Property::WORLD_ORIENTATION )
100 DALI_PROPERTY( "scale",                     VECTOR3,  true,  true,  true,  Dali::Actor::Property::SCALE )
101 DALI_PROPERTY( "scaleX",                    FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_X )
102 DALI_PROPERTY( "scaleY",                    FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_Y )
103 DALI_PROPERTY( "scaleZ",                    FLOAT,    true,  true,  true,  Dali::Actor::Property::SCALE_Z )
104 DALI_PROPERTY( "worldScale",                VECTOR3,  false, false, true,  Dali::Actor::Property::WORLD_SCALE )
105 DALI_PROPERTY( "visible",                   BOOLEAN,  true,  true,  true,  Dali::Actor::Property::VISIBLE )
106 DALI_PROPERTY( "color",                     VECTOR4,  true,  true,  true,  Dali::Actor::Property::COLOR )
107 DALI_PROPERTY( "colorRed",                  FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_RED )
108 DALI_PROPERTY( "colorGreen",                FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_GREEN )
109 DALI_PROPERTY( "colorBlue",                 FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_BLUE )
110 DALI_PROPERTY( "colorAlpha",                FLOAT,    true,  true,  true,  Dali::Actor::Property::COLOR_ALPHA )
111 DALI_PROPERTY( "worldColor",                VECTOR4,  false, false, true,  Dali::Actor::Property::WORLD_COLOR )
112 DALI_PROPERTY( "worldMatrix",               MATRIX,   false, false, true,  Dali::Actor::Property::WORLD_MATRIX )
113 DALI_PROPERTY( "name",                      STRING,   true,  false, false, Dali::Actor::Property::NAME )
114 DALI_PROPERTY( "sensitive",                 BOOLEAN,  true,  false, false, Dali::Actor::Property::SENSITIVE )
115 DALI_PROPERTY( "leaveRequired",             BOOLEAN,  true,  false, false, Dali::Actor::Property::LEAVE_REQUIRED )
116 DALI_PROPERTY( "inheritOrientation",        BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
117 DALI_PROPERTY( "inheritScale",              BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_SCALE )
118 DALI_PROPERTY( "colorMode",                 INTEGER,  true,  false, false, Dali::Actor::Property::COLOR_MODE )
119 DALI_PROPERTY( "drawMode",                  INTEGER,  true,  false, false, Dali::Actor::Property::DRAW_MODE )
120 DALI_PROPERTY( "sizeModeFactor",            VECTOR3,  true,  false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
121 DALI_PROPERTY( "widthResizePolicy",         STRING,   true,  false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
122 DALI_PROPERTY( "heightResizePolicy",        STRING,   true,  false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
123 DALI_PROPERTY( "sizeScalePolicy",           INTEGER,  true,  false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
124 DALI_PROPERTY( "widthForHeight",            BOOLEAN,  true,  false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
125 DALI_PROPERTY( "heightForWidth",            BOOLEAN,  true,  false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
126 DALI_PROPERTY( "padding",                   VECTOR4,  true,  false, false, Dali::Actor::Property::PADDING )
127 DALI_PROPERTY( "minimumSize",               VECTOR2,  true,  false, false, Dali::Actor::Property::MINIMUM_SIZE )
128 DALI_PROPERTY( "maximumSize",               VECTOR2,  true,  false, false, Dali::Actor::Property::MAXIMUM_SIZE )
129 DALI_PROPERTY( "inheritPosition",           BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_POSITION )
130 DALI_PROPERTY( "clippingMode",              STRING,   true,  false, false, Dali::Actor::Property::CLIPPING_MODE )
131 DALI_PROPERTY( "layoutDirection",           STRING,   true,  false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
132 DALI_PROPERTY( "inheritLayoutDirection",    BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
133 DALI_PROPERTY( "opacity",                   FLOAT,    true,  true,  true,  Dali::Actor::Property::OPACITY )
134 DALI_PROPERTY( "screenPosition",            VECTOR2,  false, false, false, Dali::Actor::Property::SCREEN_POSITION )
135 DALI_PROPERTY( "positionUsesAnchorPoint",   BOOLEAN,  true,  false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT )
136 DALI_PROPERTY( "culled",                    BOOLEAN,  false, false, true,  Dali::Actor::Property::CULLED )
137 DALI_PROPERTY( "id",                        INTEGER,  false, false, false, Dali::Actor::Property::ID )
138 DALI_PROPERTY( "hierarchyDepth",            INTEGER,  false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH )
139 DALI_PROPERTY( "isRoot",                    BOOLEAN,  false, false, false, Dali::Actor::Property::IS_ROOT )
140 DALI_PROPERTY( "isLayer",                   BOOLEAN,  false, false, false, Dali::Actor::Property::IS_LAYER )
141 DALI_PROPERTY( "connectedToScene",          BOOLEAN,  false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE )
142 DALI_PROPERTY( "keyboardFocusable",         BOOLEAN,  true,  false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE )
143 DALI_PROPERTY( "siblingOrder",              INTEGER,  true,  false, false, Dali::DevelActor::Property::SIBLING_ORDER )
144 DALI_PROPERTY( "updateSizeHint",            VECTOR2,  true,  false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT )
145 DALI_PROPERTY( "captureAllTouchAfterStart", BOOLEAN,  true,  false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START )
146 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
147
148 // Signals
149
150 const char* const SIGNAL_HOVERED = "hovered";
151 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
152 const char* const SIGNAL_ON_SCENE = "onScene";
153 const char* const SIGNAL_OFF_SCENE = "offScene";
154 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
155 const char* const SIGNAL_TOUCHED = "touched";
156 const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
157 const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
158 const char* const SIGNAL_CHILD_ADDED = "childAdded";
159 const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
160
161 // Actions
162
163 const char* const ACTION_SHOW = "show";
164 const char* const ACTION_HIDE = "hide";
165
166 BaseHandle CreateActor()
167 {
168   return Dali::Actor::New();
169 }
170
171 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
172
173 SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
174 SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
175 SignalConnectorType signalConnector4( mType, SIGNAL_ON_SCENE, &Actor::DoConnectSignal );
176 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_SCENE, &Actor::DoConnectSignal );
177 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
178 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
179 SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
180 SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
181 SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
182 SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
183
184 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
185 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
186
187 /**
188  * @brief Extract a given dimension from a Vector2
189  *
190  * @param[in] values The values to extract from
191  * @param[in] dimension The dimension to extract
192  * @return Return the value for the dimension
193  */
194 constexpr float GetDimensionValue( const Vector2& values, Dimension::Type dimension )
195 {
196   switch( dimension )
197   {
198     case Dimension::WIDTH:
199     {
200       return values.width;
201     }
202     case Dimension::HEIGHT:
203     {
204       return values.height;
205     }
206     default:
207     {
208       break;
209     }
210   }
211   return 0.0f;
212 }
213
214 /**
215  * @brief Extract a given dimension from a Vector3
216  *
217  * @param[in] values The values to extract from
218  * @param[in] dimension The dimension to extract
219  * @return Return the value for the dimension
220  */
221 float GetDimensionValue( const Vector3& values, Dimension::Type dimension )
222 {
223   return GetDimensionValue( values.GetVectorXY(), dimension );
224 }
225
226 /**
227  * @brief Recursively emits the visibility-changed-signal on the actor tree.
228  * @param[in] actor The actor to emit the signal on
229  * @param[in] visible The new visibility of the actor
230  * @param[in] type Whether the actor's visible property has changed or a parent's
231  */
232 void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type )
233 {
234   if( actor )
235   {
236     actor->EmitVisibilityChangedSignal( visible, type );
237
238     if( actor->GetChildCount() > 0 )
239     {
240       for( ActorPtr& child : actor->GetChildrenInternal() )
241       {
242         EmitVisibilityChangedSignalRecursively( child, visible, DevelActor::VisibilityChange::PARENT );
243       }
244     }
245   }
246 }
247
248 /// Helper for emitting a signal
249 template<typename Signal, typename Event>
250 bool EmitConsumingSignal( Actor& actor, Signal& signal, const Event& event )
251 {
252   bool consumed = false;
253
254   if( !signal.Empty() )
255   {
256     Dali::Actor handle( &actor );
257     consumed = signal.Emit( handle, event );
258   }
259
260   return consumed;
261 }
262
263 /// Helper for emitting signals with multiple parameters
264 template<typename Signal, typename... Param>
265 void EmitSignal( Actor& actor, Signal& signal, Param... params)
266 {
267   if( !signal.Empty() )
268   {
269     Dali::Actor handle( &actor );
270     signal.Emit( handle, params... );
271   }
272 }
273
274 bool ScreenToLocalInternal(
275     const Matrix& viewMatrix,
276     const Matrix& projectionMatrix,
277     const Matrix& worldMatrix,
278     const Viewport& viewport,
279     const Vector3& currentSize,
280     float& localX,
281     float& localY,
282     float screenX,
283     float screenY )
284 {
285   // Get the ModelView matrix
286   Matrix modelView;
287   Matrix::Multiply( modelView, worldMatrix, viewMatrix );
288
289   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
290   Matrix invertedMvp( false/*don't init*/);
291   Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
292   bool success = invertedMvp.Invert();
293
294   // Convert to GL coordinates
295   Vector4 screenPos( screenX - static_cast<float>( viewport.x ), static_cast<float>( viewport.height ) - screenY - static_cast<float>( viewport.y ), 0.f, 1.f );
296
297   Vector4 nearPos;
298   if( success )
299   {
300     success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), nearPos );
301   }
302
303   Vector4 farPos;
304   if( success )
305   {
306     screenPos.z = 1.0f;
307     success = Unproject( screenPos, invertedMvp, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), farPos );
308   }
309
310   if( success )
311   {
312     Vector4 local;
313     if( XyPlaneIntersect( nearPos, farPos, local ) )
314     {
315       Vector3 size = currentSize;
316       localX = local.x + size.x * 0.5f;
317       localY = local.y + size.y * 0.5f;
318     }
319     else
320     {
321       success = false;
322     }
323   }
324
325   return success;
326 }
327
328 } // unnamed namespace
329
330 ActorPtr Actor::New()
331 {
332   // pass a reference to actor, actor does not own its node
333   ActorPtr actor( new Actor( BASIC, *CreateNode() ) );
334
335   // Second-phase construction
336   actor->Initialize();
337
338   return actor;
339 }
340
341 const SceneGraph::Node* Actor::CreateNode()
342 {
343   // create node. Nodes are owned by the update manager
344   SceneGraph::Node* node = SceneGraph::Node::New();
345   OwnerPointer< SceneGraph::Node > transferOwnership( node );
346   Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
347
348   DALI_ASSERT_ALWAYS( tls && "ThreadLocalStorage is null" );
349
350   AddNodeMessage( tls->GetUpdateManager(), transferOwnership );
351
352   return node;
353 }
354
355 void Actor::SetName( const std::string& name )
356 {
357   mName = name;
358
359   // ATTENTION: string for debug purposes is not thread safe.
360   DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name );
361 }
362
363 uint32_t Actor::GetId() const
364 {
365   return GetNode().GetId();
366 }
367
368 Dali::Layer Actor::GetLayer()
369 {
370   Dali::Layer layer;
371
372   // Short-circuit for Layer derived actors
373   if( mIsLayer )
374   {
375     layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag
376   }
377
378   // Find the immediate Layer parent
379   for( Actor* parent = mParent; !layer && parent != nullptr; parent = parent->GetParent() )
380   {
381     if( parent->IsLayer() )
382     {
383       layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag
384     }
385   }
386
387   return layer;
388 }
389
390 void Actor::Add( Actor& child )
391 {
392   DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
393   DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
394
395   if( !mChildren )
396   {
397     mChildren = new ActorContainer;
398   }
399
400   Actor* const oldParent( child.mParent );
401
402   // child might already be ours
403   if( this != oldParent )
404   {
405     // if we already have parent, unparent us first
406     if( oldParent )
407     {
408       oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
409
410       // Old parent may need to readjust to missing child
411       if( oldParent->RelayoutDependentOnChildren() )
412       {
413         oldParent->RelayoutRequest();
414       }
415     }
416
417     // Guard against Add() during previous OnChildRemove callback
418     if( !child.mParent )
419     {
420       // Do this first, since user callbacks from within SetParent() may need to remove child
421       mChildren->push_back( ActorPtr( &child ) );
422
423       // SetParent asserts that child can be added
424       child.SetParent( this );
425
426       // Notification for derived classes
427       OnChildAdd( child );
428       EmitChildAddedSignal( child );
429
430       InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
431
432       // Only put in a relayout request if there is a suitable dependency
433       if( RelayoutDependentOnChildren() )
434       {
435         RelayoutRequest();
436       }
437     }
438   }
439 }
440
441 void Actor::Remove( Actor& child )
442 {
443   if( (this == &child) || (!mChildren) )
444   {
445     // no children or removing itself
446     return;
447   }
448
449   ActorPtr removed;
450
451   // Find the child in mChildren, and unparent it
452   ActorIter end = mChildren->end();
453   for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
454   {
455     ActorPtr actor = (*iter);
456
457     if( actor.Get() == &child )
458     {
459       // Keep handle for OnChildRemove notification
460       removed = actor;
461
462       // Do this first, since user callbacks from within SetParent() may need to add the child
463       mChildren->erase( iter );
464
465       DALI_ASSERT_DEBUG( actor->GetParent() == this );
466       actor->SetParent( nullptr );
467
468       break;
469     }
470   }
471
472   if( removed )
473   {
474     // Only put in a relayout request if there is a suitable dependency
475     if( RelayoutDependentOnChildren() )
476     {
477       RelayoutRequest();
478     }
479   }
480
481   // Notification for derived classes
482   OnChildRemove( child );
483   EmitChildRemovedSignal( child );
484 }
485
486 void Actor::Unparent()
487 {
488   if( mParent )
489   {
490     // Remove this actor from the parent. The remove will put a relayout request in for
491     // the parent if required
492     mParent->Remove( *this );
493     // mParent is now NULL!
494   }
495 }
496
497 uint32_t Actor::GetChildCount() const
498 {
499   return ( nullptr != mChildren ) ? static_cast<uint32_t>( mChildren->size() ) : 0; // only 4,294,967,295 children per actor
500 }
501
502 ActorPtr Actor::GetChildAt( uint32_t index ) const
503 {
504   DALI_ASSERT_ALWAYS( index < GetChildCount() );
505
506   return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() );
507 }
508
509 ActorPtr Actor::FindChildByName( const std::string& actorName )
510 {
511   ActorPtr child = nullptr;
512   if( actorName == mName )
513   {
514     child = this;
515   }
516   else if( mChildren )
517   {
518     ActorIter end = mChildren->end();
519     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
520     {
521       child = (*iter)->FindChildByName( actorName );
522
523       if( child )
524       {
525         break;
526       }
527     }
528   }
529   return child;
530 }
531
532 ActorPtr Actor::FindChildById( const uint32_t id )
533 {
534   ActorPtr child = nullptr;
535   if( id == GetId() )
536   {
537     child = this;
538   }
539   else if( mChildren )
540   {
541     ActorIter end = mChildren->end();
542     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
543     {
544       child = (*iter)->FindChildById( id );
545
546       if( child )
547       {
548         break;
549       }
550     }
551   }
552   return child;
553 }
554
555 void Actor::SetParentOrigin( const Vector3& origin )
556 {
557   // node is being used in a separate thread; queue a message to set the value & base value
558   SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin );
559
560   // Cache for event-thread access
561   if( !mParentOrigin )
562   {
563     // not allocated, check if different from default
564     if( ParentOrigin::DEFAULT != origin )
565     {
566       mParentOrigin = new Vector3( origin );
567     }
568   }
569   else
570   {
571     // check if different from current costs more than just set
572     *mParentOrigin = origin;
573   }
574 }
575
576 const Vector3& Actor::GetCurrentParentOrigin() const
577 {
578   // Cached for event-thread access
579   return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
580 }
581
582 void Actor::SetAnchorPoint( const Vector3& anchor )
583 {
584   // node is being used in a separate thread; queue a message to set the value & base value
585   SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor );
586
587   // Cache for event-thread access
588   if( !mAnchorPoint )
589   {
590     // not allocated, check if different from default
591     if( AnchorPoint::DEFAULT != anchor )
592     {
593       mAnchorPoint = new Vector3( anchor );
594     }
595   }
596   else
597   {
598     // check if different from current costs more than just set
599     *mAnchorPoint = anchor;
600   }
601 }
602
603 const Vector3& Actor::GetCurrentAnchorPoint() const
604 {
605   // Cached for event-thread access
606   return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT;
607 }
608
609 void Actor::SetPosition( float x, float y )
610 {
611   SetPosition( Vector3( x, y, 0.0f ) );
612 }
613
614 void Actor::SetPosition( float x, float y, float z )
615 {
616   SetPosition( Vector3( x, y, z ) );
617 }
618
619 void Actor::SetPosition( const Vector3& position )
620 {
621   mTargetPosition = position;
622
623   // node is being used in a separate thread; queue a message to set the value & base value
624   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position );
625 }
626
627 void Actor::SetX( float x )
628 {
629   mTargetPosition.x = x;
630
631   // node is being used in a separate thread; queue a message to set the value & base value
632   SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
633 }
634
635 void Actor::SetY( float y )
636 {
637   mTargetPosition.y = y;
638
639   // node is being used in a separate thread; queue a message to set the value & base value
640   SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
641 }
642
643 void Actor::SetZ( float z )
644 {
645   mTargetPosition.z = z;
646
647   // node is being used in a separate thread; queue a message to set the value & base value
648   SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
649 }
650
651 void Actor::TranslateBy( const Vector3& distance )
652 {
653   mTargetPosition += distance;
654
655   // node is being used in a separate thread; queue a message to set the value & base value
656   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance );
657 }
658
659 const Vector3& Actor::GetCurrentPosition() const
660 {
661   // node is being used in a separate thread; copy the value from the previous update
662   return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
663 }
664
665 const Vector3& Actor::GetCurrentWorldPosition() const
666 {
667   // node is being used in a separate thread; copy the value from the previous update
668   return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
669 }
670
671 const Vector2 Actor::GetCurrentScreenPosition() const
672 {
673   if( mScene && OnScene() )
674   {
675     Vector3 worldPosition =  GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
676     Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
677     worldPosition -= cameraPosition;
678
679     Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
680     Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene
681     Vector3 halfActorSize( actorSize * 0.5f );
682     Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
683
684     return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
685                     halfSceneSize.height + worldPosition.y - anchorPointOffSet.y );
686   }
687
688   return Vector2::ZERO;
689 }
690
691 void Actor::SetInheritPosition( bool inherit )
692 {
693   if( mInheritPosition != inherit )
694   {
695     // non animatable so keep local copy
696     mInheritPosition = inherit;
697     SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit );
698   }
699 }
700
701 void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
702 {
703   Vector3 normalizedAxis( axis.x, axis.y, axis.z );
704   normalizedAxis.Normalize();
705
706   Quaternion orientation( angle, normalizedAxis );
707
708   SetOrientation( orientation );
709 }
710
711 void Actor::SetOrientation( const Quaternion& orientation )
712 {
713   mTargetOrientation = orientation;
714
715   // node is being used in a separate thread; queue a message to set the value & base value
716   SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation );
717 }
718
719 void Actor::RotateBy( const Radian& angle, const Vector3& axis )
720 {
721   RotateBy( Quaternion(angle, axis) );
722 }
723
724 void Actor::RotateBy( const Quaternion& relativeRotation )
725 {
726   mTargetOrientation *= Quaternion( relativeRotation );
727
728   // node is being used in a separate thread; queue a message to set the value & base value
729   SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation );
730 }
731
732 const Quaternion& Actor::GetCurrentOrientation() const
733 {
734   // node is being used in a separate thread; copy the value from the previous update
735   return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
736 }
737
738 const Quaternion& Actor::GetCurrentWorldOrientation() const
739 {
740   // node is being used in a separate thread; copy the value from the previous update
741   return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() );
742 }
743
744 void Actor::SetScale( float scale )
745 {
746   SetScale( Vector3( scale, scale, scale ) );
747 }
748
749 void Actor::SetScale( float x, float y, float z )
750 {
751   SetScale( Vector3( x, y, z ) );
752 }
753
754 void Actor::SetScale( const Vector3& scale )
755 {
756   mTargetScale = scale;
757
758   // node is being used in a separate thread; queue a message to set the value & base value
759   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale );
760 }
761
762 void Actor::SetScaleX( float x )
763 {
764   mTargetScale.x = x;
765
766   // node is being used in a separate thread; queue a message to set the value & base value
767   SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x );
768 }
769
770 void Actor::SetScaleY( float y )
771 {
772   mTargetScale.y = y;
773
774   // node is being used in a separate thread; queue a message to set the value & base value
775   SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y );
776 }
777
778 void Actor::SetScaleZ( float z )
779 {
780   mTargetScale.z = z;
781
782   // node is being used in a separate thread; queue a message to set the value & base value
783   SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z );
784 }
785
786 void Actor::ScaleBy(const Vector3& relativeScale)
787 {
788   mTargetScale *= relativeScale;
789
790   // node is being used in a separate thread; queue a message to set the value & base value
791   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale );
792 }
793
794 const Vector3& Actor::GetCurrentScale() const
795 {
796   // node is being used in a separate thread; copy the value from the previous update
797   return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
798 }
799
800 const Vector3& Actor::GetCurrentWorldScale() const
801 {
802   // node is being used in a separate thread; copy the value from the previous update
803   return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() );
804 }
805
806 void Actor::SetInheritScale( bool inherit )
807 {
808   if( mInheritScale != inherit )
809   {
810     // non animatable so keep local copy
811     mInheritScale = inherit;
812     // node is being used in a separate thread; queue a message to set the value
813     SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit );
814   }
815 }
816
817 Matrix Actor::GetCurrentWorldMatrix() const
818 {
819   return GetNode().GetWorldMatrix(0);
820 }
821
822 void Actor::SetVisible( bool visible )
823 {
824   SetVisibleInternal( visible, SendMessage::TRUE );
825 }
826
827 bool Actor::IsVisible() const
828 {
829   // node is being used in a separate thread; copy the value from the previous update
830   return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() );
831 }
832
833 void Actor::SetOpacity( float opacity )
834 {
835   mTargetColor.a = opacity;
836
837   // node is being used in a separate thread; queue a message to set the value & base value
838   SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
839 }
840
841 float Actor::GetCurrentOpacity() const
842 {
843   // node is being used in a separate thread; copy the value from the previous update
844   return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
845 }
846
847 const Vector4& Actor::GetCurrentWorldColor() const
848 {
849   return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() );
850 }
851
852 void Actor::SetColor( const Vector4& color )
853 {
854   mTargetColor = color;
855
856   // node is being used in a separate thread; queue a message to set the value & base value
857   SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
858 }
859
860 void Actor::SetColorRed( float red )
861 {
862   mTargetColor.r = red;
863
864   // node is being used in a separate thread; queue a message to set the value & base value
865   SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
866 }
867
868 void Actor::SetColorGreen( float green )
869 {
870   mTargetColor.g = green;
871
872   // node is being used in a separate thread; queue a message to set the value & base value
873   SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
874 }
875
876 void Actor::SetColorBlue( float blue )
877 {
878   mTargetColor.b = blue;
879
880   // node is being used in a separate thread; queue a message to set the value & base value
881   SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
882 }
883
884 const Vector4& Actor::GetCurrentColor() const
885 {
886   // node is being used in a separate thread; copy the value from the previous update
887   return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
888 }
889
890 void Actor::SetInheritOrientation( bool inherit )
891 {
892   if( mInheritOrientation != inherit )
893   {
894     // non animatable so keep local copy
895     mInheritOrientation = inherit;
896     // node is being used in a separate thread; queue a message to set the value
897     SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit );
898   }
899 }
900
901 void Actor::SetSizeModeFactor( const Vector3& factor )
902 {
903   EnsureRelayouter();
904
905   mRelayoutData->sizeModeFactor = factor;
906 }
907
908 const Vector3& Actor::GetSizeModeFactor() const
909 {
910   if ( mRelayoutData )
911   {
912     return mRelayoutData->sizeModeFactor;
913   }
914
915   return Relayouter::DEFAULT_SIZE_MODE_FACTOR;
916 }
917
918 void Actor::SetColorMode( ColorMode colorMode )
919 {
920   // non animatable so keep local copy
921   mColorMode = colorMode;
922   // node is being used in a separate thread; queue a message to set the value
923   SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode );
924 }
925
926 void Actor::SetSize( float width, float height )
927 {
928   SetSize( Vector2( width, height ) );
929 }
930
931 void Actor::SetSize( float width, float height, float depth )
932 {
933   SetSize( Vector3( width, height, depth ) );
934 }
935
936 void Actor::SetSize( const Vector2& size )
937 {
938   SetSize( Vector3( size.width, size.height, 0.f ) );
939 }
940
941 void Actor::SetSizeInternal( const Vector2& size )
942 {
943   SetSizeInternal( Vector3( size.width, size.height, 0.f ) );
944 }
945
946 void Actor::SetSize( const Vector3& size )
947 {
948   if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
949   {
950     // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
951     SetPreferredSize( size.GetVectorXY() );
952   }
953   else
954   {
955     SetSizeInternal( size );
956   }
957 }
958
959 void Actor::SetSizeInternal( const Vector3& size )
960 {
961   // dont allow recursive loop
962   DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" );
963   // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
964   if( ( fabsf( mTargetSize.width - size.width  ) > Math::MACHINE_EPSILON_1 )||
965       ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
966       ( fabsf( mTargetSize.depth - size.depth  ) > Math::MACHINE_EPSILON_1 ) )
967   {
968     mTargetSize = size;
969
970     // node is being used in a separate thread; queue a message to set the value & base value
971     SceneGraph::NodeTransformPropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize );
972
973     // Notification for derived classes
974     mInsideOnSizeSet = true;
975     OnSizeSet( mTargetSize );
976     mInsideOnSizeSet = false;
977
978     // Raise a relayout request if the flag is not locked
979     if( mRelayoutData && !mRelayoutData->insideRelayout )
980     {
981       RelayoutRequest();
982     }
983   }
984 }
985
986 void Actor::SetWidth( float width )
987 {
988   if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
989   {
990     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
991     mRelayoutData->preferredSize.width = width;
992   }
993   else
994   {
995     mTargetSize.width = width;
996
997     // node is being used in a separate thread; queue a message to set the value & base value
998     SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
999   }
1000
1001   mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
1002
1003   RelayoutRequest();
1004 }
1005
1006 void Actor::SetHeight( float height )
1007 {
1008   if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
1009   {
1010     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
1011     mRelayoutData->preferredSize.height = height;
1012   }
1013   else
1014   {
1015     mTargetSize.height = height;
1016
1017     // node is being used in a separate thread; queue a message to set the value & base value
1018     SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height );
1019   }
1020
1021   mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
1022
1023   RelayoutRequest();
1024 }
1025
1026 void Actor::SetDepth( float depth )
1027 {
1028   mTargetSize.depth = depth;
1029
1030   mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
1031
1032   // node is being used in a separate thread; queue a message to set the value & base value
1033   SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth );
1034 }
1035
1036 Vector3 Actor::GetTargetSize() const
1037 {
1038   Vector3 size = mTargetSize;
1039
1040   if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH )
1041   {
1042     // Should return animated size if size is animated
1043     size.width = mAnimatedSize.width;
1044   }
1045   else
1046   {
1047     // Should return preferred size if size is fixed as set by SetSize
1048     if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED )
1049     {
1050       size.width = GetPreferredSize().width;
1051     }
1052   }
1053
1054   if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT )
1055   {
1056     size.height = mAnimatedSize.height;
1057   }
1058   else
1059   {
1060     if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED )
1061     {
1062       size.height = GetPreferredSize().height;
1063     }
1064   }
1065
1066   if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH )
1067   {
1068     size.depth = mAnimatedSize.depth;
1069   }
1070
1071   return size;
1072 }
1073
1074 const Vector3& Actor::GetCurrentSize() const
1075 {
1076   // node is being used in a separate thread; copy the value from the previous update
1077   return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() );
1078 }
1079
1080 Vector3 Actor::GetNaturalSize() const
1081 {
1082   // It is up to deriving classes to return the appropriate natural size
1083   return Vector3( 0.0f, 0.0f, 0.0f );
1084 }
1085
1086 void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
1087 {
1088   EnsureRelayouter().SetResizePolicy(policy, dimension, mTargetSize);
1089
1090   OnSetResizePolicy( policy, dimension );
1091
1092   // Trigger relayout on this control
1093   RelayoutRequest();
1094 }
1095
1096 ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
1097 {
1098   if ( mRelayoutData )
1099   {
1100     return mRelayoutData->GetResizePolicy(dimension);
1101   }
1102
1103   return ResizePolicy::DEFAULT;
1104 }
1105
1106 void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy )
1107 {
1108   EnsureRelayouter();
1109
1110   mRelayoutData->sizeSetPolicy = policy;
1111
1112   // Trigger relayout on this control
1113   RelayoutRequest();
1114 }
1115
1116 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
1117 {
1118   if ( mRelayoutData )
1119   {
1120     return mRelayoutData->sizeSetPolicy;
1121   }
1122
1123   return Relayouter::DEFAULT_SIZE_SCALE_POLICY;
1124 }
1125
1126 void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency )
1127 {
1128   EnsureRelayouter().SetDimensionDependency(dimension, dependency);
1129 }
1130
1131 Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const
1132 {
1133   if ( mRelayoutData )
1134   {
1135     return mRelayoutData->GetDimensionDependency(dimension);
1136   }
1137
1138   return Dimension::ALL_DIMENSIONS;   // Default
1139 }
1140
1141 void Actor::SetRelayoutEnabled( bool relayoutEnabled )
1142 {
1143   // If relayout data has not been allocated yet and the client is requesting
1144   // to disable it, do nothing
1145   if( mRelayoutData || relayoutEnabled )
1146   {
1147     EnsureRelayouter();
1148
1149     DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" );
1150
1151     mRelayoutData->relayoutEnabled = relayoutEnabled;
1152   }
1153 }
1154
1155 bool Actor::IsRelayoutEnabled() const
1156 {
1157   // Assume that if relayout data has not been allocated yet then
1158   // relayout is disabled
1159   return mRelayoutData && mRelayoutData->relayoutEnabled;
1160 }
1161
1162 void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension )
1163 {
1164   EnsureRelayouter().SetLayoutDirty(dirty, dimension);
1165 }
1166
1167 bool Actor::IsLayoutDirty( Dimension::Type dimension ) const
1168 {
1169   return mRelayoutData && mRelayoutData->IsLayoutDirty(dimension);
1170 }
1171
1172 bool Actor::RelayoutPossible( Dimension::Type dimension ) const
1173 {
1174   return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
1175 }
1176
1177 bool Actor::RelayoutRequired( Dimension::Type dimension ) const
1178 {
1179   return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
1180 }
1181
1182 uint32_t Actor::AddRenderer( Renderer& renderer )
1183 {
1184   if( !mRenderers )
1185   {
1186     mRenderers = new RendererContainer;
1187   }
1188
1189   uint32_t index = static_cast<uint32_t>( mRenderers->size() ); //  4,294,967,295 renderers per actor
1190   RendererPtr rendererPtr = RendererPtr( &renderer );
1191   mRenderers->push_back( rendererPtr );
1192   AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1193   return index;
1194 }
1195
1196 uint32_t Actor::GetRendererCount() const
1197 {
1198   uint32_t rendererCount(0);
1199   if( mRenderers )
1200   {
1201     rendererCount = static_cast<uint32_t>( mRenderers->size() ); //  4,294,967,295 renderers per actor
1202   }
1203
1204   return rendererCount;
1205 }
1206
1207 RendererPtr Actor::GetRendererAt( uint32_t index )
1208 {
1209   RendererPtr renderer;
1210   if( index < GetRendererCount() )
1211   {
1212     renderer = ( *mRenderers )[ index ];
1213   }
1214
1215   return renderer;
1216 }
1217
1218 void Actor::RemoveRenderer( Renderer& renderer )
1219 {
1220   if( mRenderers )
1221   {
1222     RendererIter end = mRenderers->end();
1223     for( RendererIter iter = mRenderers->begin(); iter != end; ++iter )
1224     {
1225       if( (*iter).Get() == &renderer )
1226       {
1227         mRenderers->erase( iter );
1228         DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() );
1229         break;
1230       }
1231     }
1232   }
1233 }
1234
1235 void Actor::RemoveRenderer( uint32_t index )
1236 {
1237   if( index < GetRendererCount() )
1238   {
1239     RendererPtr renderer = ( *mRenderers )[ index ];
1240     DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() );
1241     mRenderers->erase( mRenderers->begin()+index );
1242   }
1243 }
1244
1245 void Actor::SetDrawMode( DrawMode::Type drawMode )
1246 {
1247   // this flag is not animatable so keep the value
1248   mDrawMode = drawMode;
1249
1250   // node is being used in a separate thread; queue a message to set the value
1251   SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode );
1252 }
1253
1254 bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
1255 {
1256   // only valid when on-stage
1257   if( mScene && OnScene() )
1258   {
1259     const RenderTaskList& taskList = mScene->GetRenderTaskList();
1260
1261     Vector2 converted( screenX, screenY );
1262
1263     // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1264     uint32_t taskCount = taskList.GetTaskCount();
1265     for( uint32_t i = taskCount; i > 0; --i )
1266     {
1267       RenderTaskPtr task = taskList.GetTask( i - 1 );
1268       if( ScreenToLocal( *task, localX, localY, screenX, screenY ) )
1269       {
1270         // found a task where this conversion was ok so return
1271         return true;
1272       }
1273     }
1274   }
1275   return false;
1276 }
1277
1278 bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
1279 {
1280   bool retval = false;
1281   // only valid when on-stage
1282   if( OnScene() )
1283   {
1284     CameraActor* camera = renderTask.GetCameraActor();
1285     if( camera )
1286     {
1287       Viewport viewport;
1288       renderTask.GetViewport( viewport );
1289
1290       // need to translate coordinates to render tasks coordinate space
1291       Vector2 converted( screenX, screenY );
1292       if( renderTask.TranslateCoordinates( converted ) )
1293       {
1294         retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y );
1295       }
1296     }
1297   }
1298   return retval;
1299 }
1300
1301 bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
1302 {
1303   return OnScene() && ScreenToLocalInternal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), viewport, GetCurrentSize(), localX, localY, screenX, screenY);
1304 }
1305
1306 ActorGestureData& Actor::GetGestureData()
1307 {
1308   // Likely scenario is that once gesture-data is created for this actor, the actor will require
1309   // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1310   if( nullptr == mGestureData )
1311   {
1312     mGestureData = new ActorGestureData;
1313   }
1314   return *mGestureData;
1315 }
1316
1317 bool Actor::IsGestureRequired( GestureType::Value type ) const
1318 {
1319   return mGestureData && mGestureData->IsGestureRequired( type );
1320 }
1321
1322 bool Actor::EmitInterceptTouchEventSignal( const Dali::TouchEvent& touch )
1323 {
1324   return EmitConsumingSignal( *this, mInterceptTouchedSignal, touch );
1325 }
1326
1327 bool Actor::EmitTouchEventSignal( const Dali::TouchEvent& touch )
1328 {
1329   return EmitConsumingSignal( *this, mTouchedSignal, touch );
1330 }
1331
1332 bool Actor::EmitHoverEventSignal( const Dali::HoverEvent& event )
1333 {
1334   return EmitConsumingSignal( *this, mHoveredSignal, event );
1335 }
1336
1337 bool Actor::EmitWheelEventSignal( const Dali::WheelEvent& event )
1338 {
1339   return EmitConsumingSignal( *this, mWheelEventSignal, event );
1340 }
1341
1342 void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type )
1343 {
1344   EmitSignal( *this, mVisibilityChangedSignal, visible, type );
1345 }
1346
1347 void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
1348 {
1349   EmitSignal( *this, mLayoutDirectionChangedSignal, type );
1350 }
1351
1352 void Actor::EmitChildAddedSignal( Actor& child )
1353 {
1354   EmitSignal( child, mChildAddedSignal );
1355 }
1356
1357 void Actor::EmitChildRemovedSignal( Actor& child )
1358 {
1359   EmitSignal( child, mChildRemovedSignal );
1360 }
1361
1362 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1363 {
1364   bool connected( true );
1365   Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
1366
1367   if( 0 == signalName.compare( SIGNAL_HOVERED ) )
1368   {
1369     actor->HoveredSignal().Connect( tracker, functor );
1370   }
1371   else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
1372   {
1373     actor->WheelEventSignal().Connect( tracker, functor );
1374   }
1375   else if( 0 == signalName.compare( SIGNAL_ON_SCENE ) )
1376   {
1377     actor->OnSceneSignal().Connect( tracker, functor );
1378   }
1379   else if( 0 == signalName.compare( SIGNAL_OFF_SCENE ) )
1380   {
1381     actor->OffSceneSignal().Connect( tracker, functor );
1382   }
1383   else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
1384   {
1385     actor->OnRelayoutSignal().Connect( tracker, functor );
1386   }
1387   else if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
1388   {
1389     actor->TouchedSignal().Connect( tracker, functor );
1390   }
1391   else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
1392   {
1393     actor->VisibilityChangedSignal().Connect( tracker, functor );
1394   }
1395   else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
1396   {
1397     actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
1398   }
1399   else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
1400   {
1401     actor->ChildAddedSignal().Connect( tracker, functor );
1402   }
1403   else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
1404   {
1405     actor->ChildRemovedSignal().Connect( tracker, functor );
1406   }
1407   else
1408   {
1409     // signalName does not match any signal
1410     connected = false;
1411   }
1412
1413   return connected;
1414 }
1415
1416 Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
1417 : Object( &node ),
1418   mScene( nullptr ),
1419   mParent( nullptr ),
1420   mChildren( nullptr ),
1421   mRenderers( nullptr ),
1422   mParentOrigin( nullptr ),
1423   mAnchorPoint( nullptr ),
1424   mRelayoutData( nullptr ),
1425   mGestureData( nullptr ),
1426   mInterceptTouchedSignal(),
1427   mTouchedSignal(),
1428   mHoveredSignal(),
1429   mWheelEventSignal(),
1430   mOnSceneSignal(),
1431   mOffSceneSignal(),
1432   mOnRelayoutSignal(),
1433   mVisibilityChangedSignal(),
1434   mLayoutDirectionChangedSignal(),
1435   mChildAddedSignal(),
1436   mChildRemovedSignal(),
1437   mChildOrderChangedSignal(),
1438   mTargetOrientation( Quaternion::IDENTITY ),
1439   mTargetColor( Color::WHITE ),
1440   mTargetSize( Vector3::ZERO ),
1441   mTargetPosition( Vector3::ZERO ),
1442   mTargetScale( Vector3::ONE ),
1443   mAnimatedSize( Vector3::ZERO ),
1444   mName(),
1445   mSortedDepth( 0u ),
1446   mDepth( 0u ),
1447   mUseAnimatedSize( AnimatedSizeFlag::CLEAR ),
1448   mIsRoot( ROOT_LAYER == derivedType ),
1449   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
1450   mIsOnScene( false ),
1451   mSensitive( true ),
1452   mLeaveRequired( false ),
1453   mKeyboardFocusable( false ),
1454   mOnSceneSignalled( false ),
1455   mInsideOnSizeSet( false ),
1456   mInheritPosition( true ),
1457   mInheritOrientation( true ),
1458   mInheritScale( true ),
1459   mPositionUsesAnchorPoint( true ),
1460   mVisible( true ),
1461   mInheritLayoutDirection( true ),
1462   mCaptureAllTouchAfterStart( false ),
1463   mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
1464   mDrawMode( DrawMode::NORMAL ),
1465   mColorMode( Node::DEFAULT_COLOR_MODE ),
1466   mClippingMode( ClippingMode::DISABLED )
1467 {
1468 }
1469
1470 void Actor::Initialize()
1471 {
1472   OnInitialize();
1473
1474   GetEventThreadServices().RegisterObject( this );
1475 }
1476
1477 Actor::~Actor()
1478 {
1479   // Remove mParent pointers from children even if we're destroying core,
1480   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1481   if( mChildren )
1482   {
1483     ActorConstIter endIter = mChildren->end();
1484     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
1485     {
1486       (*iter)->SetParent( nullptr );
1487     }
1488   }
1489   delete mChildren;
1490   delete mRenderers;
1491
1492   // Guard to allow handle destruction after Core has been destroyed
1493   if( EventThreadServices::IsCoreRunning() )
1494   {
1495     // Root layer will destroy its node in its own destructor
1496     if ( !mIsRoot )
1497     {
1498       DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
1499
1500       GetEventThreadServices().UnregisterObject( this );
1501     }
1502   }
1503
1504   // Cleanup optional gesture data
1505   delete mGestureData;
1506
1507   // Cleanup optional parent origin and anchor
1508   delete mParentOrigin;
1509   delete mAnchorPoint;
1510
1511   // Delete optional relayout data
1512   delete mRelayoutData;
1513 }
1514
1515 void Actor::ConnectToScene( uint32_t parentDepth )
1516 {
1517   // This container is used instead of walking the Actor hierarchy.
1518   // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1519   ActorContainer connectionList;
1520
1521   if( mScene )
1522   {
1523     mScene->RequestRebuildDepthTree();
1524   }
1525
1526   // This stage is atomic i.e. not interrupted by user callbacks.
1527   RecursiveConnectToScene( connectionList, parentDepth + 1 );
1528
1529   // Notify applications about the newly connected actors.
1530   const ActorIter endIter = connectionList.end();
1531   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
1532   {
1533     (*iter)->NotifyStageConnection();
1534   }
1535
1536   RelayoutRequest();
1537 }
1538
1539 void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t depth )
1540 {
1541   DALI_ASSERT_ALWAYS( !OnScene() );
1542
1543   mIsOnScene = true;
1544   mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice
1545
1546   ConnectToSceneGraph();
1547
1548   // Notification for internal derived classes
1549   OnSceneConnectionInternal();
1550
1551   // This stage is atomic; avoid emitting callbacks until all Actors are connected
1552   connectionList.push_back( ActorPtr( this ) );
1553
1554   // Recursively connect children
1555   if( mChildren )
1556   {
1557     ActorConstIter endIter = mChildren->end();
1558     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
1559     {
1560       (*iter)->SetScene( *mScene );
1561       (*iter)->RecursiveConnectToScene( connectionList, depth + 1 );
1562     }
1563   }
1564 }
1565
1566 /**
1567  * This method is called when the Actor is connected to the Stage.
1568  * The parent must have added its Node to the scene-graph.
1569  * The child must connect its Node to the parent's Node.
1570  * This is recursive; the child calls ConnectToScene() for its children.
1571  */
1572 void Actor::ConnectToSceneGraph()
1573 {
1574   DALI_ASSERT_DEBUG( mParent != NULL);
1575
1576   // Reparent Node in next Update
1577   ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() );
1578
1579   // Request relayout on all actors that are added to the scenegraph
1580   RelayoutRequest();
1581
1582   // Notification for Object::Observers
1583   OnSceneObjectAdd();
1584 }
1585
1586 void Actor::NotifyStageConnection()
1587 {
1588   // Actors can be removed (in a callback), before the on-stage stage is reported.
1589   // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1590   if( OnScene() && !mOnSceneSignalled )
1591   {
1592     // Notification for external (CustomActor) derived classes
1593     OnSceneConnectionExternal( mDepth );
1594
1595     if( !mOnSceneSignal.Empty() )
1596     {
1597       Dali::Actor handle( this );
1598       mOnSceneSignal.Emit( handle );
1599     }
1600
1601     // Guard against Remove during callbacks
1602     if( OnScene() )
1603     {
1604       mOnSceneSignalled = true; // signal required next time Actor is removed
1605     }
1606   }
1607 }
1608
1609 void Actor::DisconnectFromStage()
1610 {
1611   // This container is used instead of walking the Actor hierachy.
1612   // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1613   ActorContainer disconnectionList;
1614
1615   if( mScene )
1616   {
1617     mScene->RequestRebuildDepthTree();
1618   }
1619
1620   // This stage is atomic i.e. not interrupted by user callbacks
1621   RecursiveDisconnectFromStage( disconnectionList );
1622
1623   // Notify applications about the newly disconnected actors.
1624   const ActorIter endIter = disconnectionList.end();
1625   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
1626   {
1627     (*iter)->NotifyStageDisconnection();
1628   }
1629 }
1630
1631 void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
1632 {
1633   // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
1634   mIsOnScene = false;
1635
1636   // Recursively disconnect children
1637   if( mChildren )
1638   {
1639     ActorConstIter endIter = mChildren->end();
1640     for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
1641     {
1642       (*iter)->RecursiveDisconnectFromStage( disconnectionList );
1643     }
1644   }
1645
1646   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
1647   disconnectionList.push_back( ActorPtr( this ) );
1648
1649   // Notification for internal derived classes
1650   OnSceneDisconnectionInternal();
1651
1652   DisconnectFromSceneGraph();
1653 }
1654
1655 /**
1656  * This method is called by an actor or its parent, before a node removal message is sent.
1657  * This is recursive; the child calls DisconnectFromStage() for its children.
1658  */
1659 void Actor::DisconnectFromSceneGraph()
1660 {
1661   // Notification for Object::Observers
1662   OnSceneObjectRemove();
1663 }
1664
1665 void Actor::NotifyStageDisconnection()
1666 {
1667   // Actors can be added (in a callback), before the off-stage state is reported.
1668   // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1669   // only do this step if there is a stage, i.e. Core is not being shut down
1670   if ( EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled )
1671   {
1672     // Notification for external (CustomeActor) derived classes
1673     OnSceneDisconnectionExternal();
1674
1675     if( !mOffSceneSignal.Empty() )
1676     {
1677       Dali::Actor handle( this );
1678       mOffSceneSignal.Emit( handle );
1679     }
1680
1681     // Guard against Add during callbacks
1682     if( !OnScene() )
1683     {
1684       mOnSceneSignalled = false; // signal required next time Actor is added
1685     }
1686   }
1687 }
1688
1689 bool Actor::IsNodeConnected() const
1690 {
1691   bool connected( false );
1692
1693   if( OnScene() )
1694   {
1695     if( IsRoot() || GetNode().GetParent() )
1696     {
1697       connected = true;
1698     }
1699   }
1700
1701   return connected;
1702 }
1703
1704 // This method initiates traversal of the actor tree using depth-first
1705 // traversal to set a depth index based on traversal order. It sends a
1706 // single message to update manager to update all the actor's nodes in
1707 // this tree with the depth index. The sceneGraphNodeDepths vector's
1708 // elements are ordered by depth, and could be used to reduce sorting
1709 // in the update thread.
1710 void Actor::RebuildDepthTree()
1711 {
1712   DALI_LOG_TIMER_START(depthTimer);
1713
1714   // Vector of scene-graph nodes and their depths to send to UpdateManager
1715   // in a single message
1716   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
1717
1718   int32_t depthIndex = 1;
1719   DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
1720
1721   SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
1722   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1723 }
1724
1725 void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex )
1726 {
1727   mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
1728   sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( &GetNode() ), mSortedDepth );
1729
1730   // Create/add to children of this node
1731   if( mChildren )
1732   {
1733     for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
1734     {
1735       Actor* childActor = (*it).Get();
1736       ++depthIndex;
1737       childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
1738     }
1739   }
1740 }
1741
1742 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
1743 {
1744   PropertyHandler::SetDefaultProperty(*this, index, property);
1745 }
1746
1747 // TODO: This method needs to be removed
1748 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
1749 {
1750   PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1751 }
1752
1753 Property::Value Actor::GetDefaultProperty( Property::Index index ) const
1754 {
1755   Property::Value value;
1756
1757   if( ! GetCachedPropertyValue( index, value ) )
1758   {
1759     // If property value is not stored in the event-side, then it must be a scene-graph only property
1760     GetCurrentPropertyValue( index, value );
1761   }
1762
1763   return value;
1764 }
1765
1766 Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const
1767 {
1768   Property::Value value;
1769
1770   if( ! GetCurrentPropertyValue( index, value ) )
1771   {
1772     // If unable to retrieve scene-graph property value, then it must be an event-side only property
1773     GetCachedPropertyValue( index, value );
1774   }
1775
1776   return value;
1777 }
1778
1779 void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
1780 {
1781   PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1782 }
1783
1784 const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
1785 {
1786   const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1787   if( !property )
1788   {
1789     // not our property, ask base
1790     property = Object::GetSceneObjectAnimatableProperty( index );
1791   }
1792
1793   return property;
1794 }
1795
1796 const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const
1797 {
1798   const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1799   if( !property )
1800   {
1801     // reuse animatable property getter as animatable properties are inputs as well
1802     // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1803     property = GetSceneObjectAnimatableProperty( index );
1804   }
1805
1806   return property;
1807 }
1808
1809 int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const
1810 {
1811   int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1812   if( Property::INVALID_COMPONENT_INDEX == componentIndex )
1813   {
1814     // ask base
1815     componentIndex = Object::GetPropertyComponentIndex( index );
1816   }
1817
1818   return componentIndex;
1819 }
1820
1821 void Actor::SetParent( Actor* parent )
1822 {
1823   if( parent )
1824   {
1825     DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" );
1826
1827     mParent = parent;
1828
1829     mScene = parent->mScene;
1830
1831     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1832          parent->OnScene() )
1833     {
1834       // Instruct each actor to create a corresponding node in the scene graph
1835       ConnectToScene( parent->GetHierarchyDepth() );
1836     }
1837
1838     // Resolve the name and index for the child properties if any
1839     ResolveChildProperties();
1840   }
1841   else // parent being set to NULL
1842   {
1843     DALI_ASSERT_ALWAYS( mParent != nullptr && "Actor should have a parent" );
1844
1845     mParent = nullptr;
1846
1847     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1848          OnScene() )
1849     {
1850       // Disconnect the Node & its children from the scene-graph.
1851       DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() );
1852
1853       // Instruct each actor to discard pointers to the scene-graph
1854       DisconnectFromStage();
1855     }
1856
1857     mScene = nullptr;
1858   }
1859 }
1860
1861 bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
1862 {
1863   bool done = false;
1864   Actor* actor = dynamic_cast< Actor* >( object );
1865
1866   if( actor )
1867   {
1868     if( 0 == actionName.compare( ACTION_SHOW ) )
1869     {
1870       actor->SetVisible( true );
1871       done = true;
1872     }
1873     else if( 0 == actionName.compare( ACTION_HIDE ) )
1874     {
1875       actor->SetVisible( false );
1876       done = true;
1877     }
1878   }
1879
1880   return done;
1881 }
1882
1883 Rect<> Actor::CalculateScreenExtents( ) const
1884 {
1885   auto screenPosition = GetCurrentScreenPosition();
1886   Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
1887   Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
1888   Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y );
1889   return { position.x, position.y, size.x, size.y };
1890 }
1891
1892 bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
1893 {
1894   return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1895 }
1896
1897 bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value  ) const
1898 {
1899   return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1900 }
1901
1902 Actor::Relayouter& Actor::EnsureRelayouter()
1903 {
1904   // Assign relayouter
1905   if( !mRelayoutData )
1906   {
1907     mRelayoutData = new Relayouter();
1908   }
1909
1910   return *mRelayoutData;
1911 }
1912
1913 bool Actor::RelayoutDependentOnParent( Dimension::Type dimension )
1914 {
1915   // Check if actor is dependent on parent
1916   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1917   {
1918     if( ( dimension & ( 1 << i ) ) )
1919     {
1920       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
1921       if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
1922       {
1923         return true;
1924       }
1925     }
1926   }
1927
1928   return false;
1929 }
1930
1931 bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension )
1932 {
1933   // Check if actor is dependent on children
1934   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1935   {
1936     if( ( dimension & ( 1 << i ) ) )
1937     {
1938       const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) );
1939       switch( resizePolicy )
1940       {
1941         case ResizePolicy::FIT_TO_CHILDREN:
1942         case ResizePolicy::USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
1943         {
1944           return true;
1945         }
1946
1947         default:
1948         {
1949           break;
1950         }
1951       }
1952     }
1953   }
1954
1955   return false;
1956 }
1957
1958 bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension )
1959 {
1960   return Actor::RelayoutDependentOnChildren( dimension );
1961 }
1962
1963 bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension )
1964 {
1965   // Check each possible dimension and see if it is dependent on the input one
1966   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1967   {
1968     if( dimension & ( 1 << i ) )
1969     {
1970       return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
1971     }
1972   }
1973
1974   return false;
1975 }
1976
1977 void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension )
1978 {
1979   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1980   {
1981     if( dimension & ( 1 << i ) )
1982     {
1983       mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
1984     }
1985   }
1986 }
1987
1988 float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const
1989 {
1990   // If more than one dimension is requested, just return the first one found
1991   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
1992   {
1993     if( ( dimension & ( 1 << i ) ) )
1994     {
1995       return mRelayoutData->negotiatedDimensions[ i ];
1996     }
1997   }
1998
1999   return 0.0f;   // Default
2000 }
2001
2002 void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension )
2003 {
2004   EnsureRelayouter().SetPadding( padding, dimension );
2005 }
2006
2007 Vector2 Actor::GetPadding( Dimension::Type dimension ) const
2008 {
2009   if ( mRelayoutData )
2010   {
2011     // If more than one dimension is requested, just return the first one found
2012     for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
2013     {
2014       if( ( dimension & ( 1 << i ) ) )
2015       {
2016         return mRelayoutData->dimensionPadding[ i ];
2017       }
2018     }
2019   }
2020
2021   return Relayouter::DEFAULT_DIMENSION_PADDING;
2022 }
2023
2024 void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension )
2025 {
2026   EnsureRelayouter().SetLayoutNegotiated(negotiated, dimension);
2027 }
2028
2029 bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const
2030 {
2031   return mRelayoutData && mRelayoutData->IsLayoutNegotiated(dimension);
2032 }
2033
2034 float Actor::GetHeightForWidthBase( float width )
2035 {
2036   float height = 0.0f;
2037
2038   const Vector3 naturalSize = GetNaturalSize();
2039   if( naturalSize.width > 0.0f )
2040   {
2041     height = naturalSize.height * width / naturalSize.width;
2042   }
2043   else // we treat 0 as 1:1 aspect ratio
2044   {
2045     height = width;
2046   }
2047
2048   return height;
2049 }
2050
2051 float Actor::GetWidthForHeightBase( float height )
2052 {
2053   float width = 0.0f;
2054
2055   const Vector3 naturalSize = GetNaturalSize();
2056   if( naturalSize.height > 0.0f )
2057   {
2058     width = naturalSize.width * height / naturalSize.height;
2059   }
2060   else // we treat 0 as 1:1 aspect ratio
2061   {
2062     width = height;
2063   }
2064
2065   return width;
2066 }
2067
2068 float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension )
2069 {
2070   // Fill to parent, taking size mode factor into account
2071   switch( child.GetResizePolicy( dimension ) )
2072   {
2073     case ResizePolicy::FILL_TO_PARENT:
2074     {
2075       return GetLatestSize( dimension );
2076     }
2077
2078     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2079     {
2080       return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
2081     }
2082
2083     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2084     {
2085       return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension );
2086     }
2087
2088     default:
2089     {
2090       return GetLatestSize( dimension );
2091     }
2092   }
2093 }
2094
2095 float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
2096 {
2097   // Can be overridden in derived class
2098   return CalculateChildSizeBase( child, dimension );
2099 }
2100
2101 float Actor::GetHeightForWidth( float width )
2102 {
2103   // Can be overridden in derived class
2104   return GetHeightForWidthBase( width );
2105 }
2106
2107 float Actor::GetWidthForHeight( float height )
2108 {
2109   // Can be overridden in derived class
2110   return GetWidthForHeightBase( height );
2111 }
2112
2113 float Actor::GetLatestSize( Dimension::Type dimension ) const
2114 {
2115   return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
2116 }
2117
2118 float Actor::GetRelayoutSize( Dimension::Type dimension ) const
2119 {
2120   Vector2 padding = GetPadding( dimension );
2121
2122   return GetLatestSize( dimension ) + padding.x + padding.y;
2123 }
2124
2125 float Actor::NegotiateFromParent( Dimension::Type dimension )
2126 {
2127   Actor* parent = GetParent();
2128   if( parent )
2129   {
2130     Vector2 padding( GetPadding( dimension ) );
2131     Vector2 parentPadding( parent->GetPadding( dimension ) );
2132     return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
2133   }
2134
2135   return 0.0f;
2136 }
2137
2138 float Actor::NegotiateFromChildren( Dimension::Type dimension )
2139 {
2140   float maxDimensionPoint = 0.0f;
2141
2142   for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
2143   {
2144     ActorPtr child = GetChildAt( i );
2145
2146     if( !child->RelayoutDependentOnParent( dimension ) )
2147     {
2148       // Calculate the min and max points that the children range across
2149       float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension );
2150       float dimensionSize = child->GetRelayoutSize( dimension );
2151       maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize );
2152     }
2153   }
2154
2155   return maxDimensionPoint;
2156 }
2157
2158 float Actor::GetSize( Dimension::Type dimension ) const
2159 {
2160   return GetDimensionValue( mTargetSize, dimension );
2161 }
2162
2163 float Actor::GetNaturalSize( Dimension::Type dimension ) const
2164 {
2165   return GetDimensionValue( GetNaturalSize(), dimension );
2166 }
2167
2168 float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize )
2169 {
2170   switch( GetResizePolicy( dimension ) )
2171   {
2172     case ResizePolicy::USE_NATURAL_SIZE:
2173     {
2174       return GetNaturalSize( dimension );
2175     }
2176
2177     case ResizePolicy::FIXED:
2178     {
2179       return GetDimensionValue( GetPreferredSize(), dimension );
2180     }
2181
2182     case ResizePolicy::USE_ASSIGNED_SIZE:
2183     {
2184       return GetDimensionValue( maximumSize, dimension );
2185     }
2186
2187     case ResizePolicy::FILL_TO_PARENT:
2188     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2189     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2190     {
2191       return NegotiateFromParent( dimension );
2192     }
2193
2194     case ResizePolicy::FIT_TO_CHILDREN:
2195     {
2196       return NegotiateFromChildren( dimension );
2197     }
2198
2199     case ResizePolicy::DIMENSION_DEPENDENCY:
2200     {
2201       const Dimension::Type dimensionDependency = GetDimensionDependency( dimension );
2202
2203       // Custom rules
2204       if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT )
2205       {
2206         return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) );
2207       }
2208
2209       if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH )
2210       {
2211         return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) );
2212       }
2213
2214       break;
2215     }
2216
2217     default:
2218     {
2219       break;
2220     }
2221   }
2222
2223   return 0.0f;  // Default
2224 }
2225
2226 void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
2227 {
2228   // Check if it needs to be negotiated
2229   if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
2230   {
2231     // Check that we havn't gotten into an infinite loop
2232     ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
2233     bool recursionFound = false;
2234     for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
2235     {
2236       if( *it == searchActor )
2237       {
2238         recursionFound = true;
2239         break;
2240       }
2241     }
2242
2243     if( !recursionFound )
2244     {
2245       // Record the path that we have taken
2246       recursionStack.push_back( ActorDimensionPair( this, dimension ) );
2247
2248       // Dimension dependency check
2249       for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
2250       {
2251         Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
2252
2253         if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
2254         {
2255           NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
2256         }
2257       }
2258
2259       // Parent dependency check
2260       Actor* parent = GetParent();
2261       if( parent && RelayoutDependentOnParent( dimension ) )
2262       {
2263         parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
2264       }
2265
2266       // Children dependency check
2267       if( RelayoutDependentOnChildren( dimension ) )
2268       {
2269         for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
2270         {
2271           ActorPtr child = GetChildAt( i );
2272
2273           // Only relayout child first if it is not dependent on this actor
2274           if( !child->RelayoutDependentOnParent( dimension ) )
2275           {
2276             child->NegotiateDimension( dimension, allocatedSize, recursionStack );
2277           }
2278         }
2279       }
2280
2281       // For deriving classes
2282       OnCalculateRelayoutSize( dimension );
2283
2284       // All dependencies checked, calculate the size and set negotiated flag
2285       const float newSize = Relayouter::ClampDimension( *this, CalculateSize( dimension, allocatedSize ), dimension );
2286
2287       SetNegotiatedDimension( newSize, dimension );
2288       SetLayoutNegotiated( true, dimension );
2289
2290       // For deriving classes
2291       OnLayoutNegotiated( newSize, dimension );
2292
2293       // This actor has been successfully processed, pop it off the recursion stack
2294       recursionStack.pop_back();
2295     }
2296     else
2297     {
2298       // TODO: Break infinite loop
2299       SetLayoutNegotiated( true, dimension );
2300     }
2301   }
2302 }
2303
2304 void Actor::NegotiateDimensions( const Vector2& allocatedSize )
2305 {
2306   // Negotiate all dimensions that require it
2307   ActorDimensionStack recursionStack;
2308
2309   for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
2310   {
2311     const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
2312
2313     // Negotiate
2314     NegotiateDimension( dimension, allocatedSize, recursionStack );
2315   }
2316 }
2317
2318 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
2319 {
2320   return mRelayoutData->ApplySizeSetPolicy(*this, size);
2321 }
2322
2323 void Actor::SetNegotiatedSize( RelayoutContainer& container )
2324 {
2325   // Do the set actor size
2326   Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) );
2327
2328   // Adjust for size set policy
2329   negotiatedSize = ApplySizeSetPolicy( negotiatedSize );
2330
2331   // Lock the flag to stop recursive relayouts on set size
2332   mRelayoutData->insideRelayout = true;
2333   SetSize( negotiatedSize );
2334   mRelayoutData->insideRelayout = false;
2335
2336   // Clear flags for all dimensions
2337   SetLayoutDirty( false );
2338
2339   // Give deriving classes a chance to respond
2340   OnRelayout( negotiatedSize, container );
2341
2342   if( !mOnRelayoutSignal.Empty() )
2343   {
2344     Dali::Actor handle( this );
2345     mOnRelayoutSignal.Emit( handle );
2346   }
2347 }
2348
2349 void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
2350 {
2351   // Force a size negotiation for actors that has assigned size during relayout
2352   // This is required as otherwise the flags that force a relayout will not
2353   // necessarilly be set. This will occur if the actor has already been laid out.
2354   // The dirty flags are then cleared. Then if the actor is added back into the
2355   // relayout container afterwards, the dirty flags would still be clear...
2356   // causing a relayout to be skipped. Here we force any actors added to the
2357   // container to be relayed out.
2358   DALI_LOG_TIMER_START( NegSizeTimer1 );
2359
2360   if( GetUseAssignedSize(Dimension::WIDTH ) )
2361   {
2362     SetLayoutNegotiated( false, Dimension::WIDTH );
2363   }
2364   if( GetUseAssignedSize( Dimension::HEIGHT ) )
2365   {
2366     SetLayoutNegotiated( false, Dimension::HEIGHT );
2367   }
2368
2369   // Do the negotiation
2370   NegotiateDimensions( allocatedSize );
2371
2372   // Set the actor size
2373   SetNegotiatedSize( container );
2374
2375   // Negotiate down to children
2376   for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
2377   {
2378     ActorPtr child = GetChildAt( i );
2379
2380     // Forces children that have already been laid out to be relayed out
2381     // if they have assigned size during relayout.
2382     if( child->GetUseAssignedSize(Dimension::WIDTH) )
2383     {
2384       child->SetLayoutNegotiated(false, Dimension::WIDTH);
2385       child->SetLayoutDirty(true, Dimension::WIDTH);
2386     }
2387
2388     if( child->GetUseAssignedSize(Dimension::HEIGHT) )
2389     {
2390       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
2391       child->SetLayoutDirty(true, Dimension::HEIGHT);
2392     }
2393
2394     // Only relayout if required
2395     if( child->RelayoutRequired() )
2396     {
2397       container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
2398     }
2399   }
2400   DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
2401 }
2402
2403 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
2404 {
2405   if( mRelayoutData )
2406   {
2407     mRelayoutData->SetUseAssignedSize(use, dimension);
2408   }
2409 }
2410
2411 bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
2412 {
2413   return mRelayoutData && mRelayoutData->GetUseAssignedSize(dimension);
2414 }
2415
2416 void Actor::RelayoutRequest( Dimension::Type dimension )
2417 {
2418   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
2419   if( relayoutController )
2420   {
2421     Dali::Actor self( this );
2422     relayoutController->RequestRelayout( self, dimension );
2423   }
2424 }
2425
2426 void Actor::SetPreferredSize( const Vector2& size )
2427 {
2428   EnsureRelayouter();
2429
2430   // If valid width or height, then set the resize policy to FIXED
2431   // A 0 width or height may also be required so if the resize policy has not been changed, i.e. is still set to DEFAULT,
2432   // then change to FIXED as well
2433
2434   if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
2435   {
2436     SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
2437   }
2438
2439   if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
2440   {
2441     SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
2442   }
2443
2444   mRelayoutData->preferredSize = size;
2445
2446   mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
2447
2448   RelayoutRequest();
2449 }
2450
2451 Vector2 Actor::GetPreferredSize() const
2452 {
2453   if ( mRelayoutData )
2454   {
2455     return Vector2( mRelayoutData->preferredSize );
2456   }
2457
2458   return Relayouter::DEFAULT_PREFERRED_SIZE;
2459 }
2460
2461 void Actor::SetMinimumSize( float size, Dimension::Type dimension )
2462 {
2463   EnsureRelayouter().SetMinimumSize(size, dimension);
2464   RelayoutRequest();
2465 }
2466
2467 float Actor::GetMinimumSize( Dimension::Type dimension ) const
2468 {
2469   if ( mRelayoutData )
2470   {
2471     return mRelayoutData->GetMinimumSize(dimension);
2472   }
2473
2474   return 0.0f;  // Default
2475 }
2476
2477 void Actor::SetMaximumSize( float size, Dimension::Type dimension )
2478 {
2479   EnsureRelayouter().SetMaximumSize(size, dimension);
2480   RelayoutRequest();
2481 }
2482
2483 float Actor::GetMaximumSize( Dimension::Type dimension ) const
2484 {
2485   if ( mRelayoutData )
2486   {
2487     return mRelayoutData->GetMaximumSize(dimension);
2488   }
2489
2490   return FLT_MAX;  // Default
2491 }
2492
2493 void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
2494 {
2495   if( mVisible != visible )
2496   {
2497     if( sendMessage == SendMessage::TRUE )
2498     {
2499       // node is being used in a separate thread; queue a message to set the value & base value
2500       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
2501     }
2502
2503     mVisible = visible;
2504
2505     // Emit the signal on this actor and all its children
2506     EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
2507   }
2508 }
2509
2510 void Actor::SetSiblingOrder( uint32_t order )
2511 {
2512   if ( mParent )
2513   {
2514     ActorContainer& siblings = *(mParent->mChildren);
2515     uint32_t currentOrder = GetSiblingOrder();
2516
2517     if( order != currentOrder )
2518     {
2519       if( order == 0 )
2520       {
2521         LowerToBottom();
2522       }
2523       else if( order < siblings.size() -1 )
2524       {
2525         if( order > currentOrder )
2526         {
2527           RaiseAbove( *siblings[order] );
2528         }
2529         else
2530         {
2531           LowerBelow( *siblings[order] );
2532         }
2533       }
2534       else
2535       {
2536         RaiseToTop();
2537       }
2538     }
2539   }
2540 }
2541
2542 uint32_t Actor::GetSiblingOrder() const
2543 {
2544   uint32_t order = 0;
2545
2546   if ( mParent )
2547   {
2548     ActorContainer& siblings = *(mParent->mChildren);
2549     for( std::size_t i = 0; i < siblings.size(); ++i )
2550     {
2551       if( siblings[i] == this )
2552       {
2553         order = static_cast<uint32_t>( i );
2554         break;
2555       }
2556     }
2557   }
2558
2559   return order;
2560 }
2561
2562 void Actor::RequestRebuildDepthTree()
2563 {
2564   if( mIsOnScene )
2565   {
2566     if( mScene )
2567     {
2568       mScene->RequestRebuildDepthTree();
2569     }
2570   }
2571 }
2572
2573 void Actor::Raise()
2574 {
2575   if ( mParent )
2576   {
2577     ActorContainer& siblings = *(mParent->mChildren);
2578     if( siblings.back() != this ) // If not already at end
2579     {
2580       for( std::size_t i=0; i<siblings.size(); ++i )
2581       {
2582         if( siblings[i] == this )
2583         {
2584           // Swap with next
2585           ActorPtr next = siblings[i+1];
2586           siblings[i+1] = this;
2587           siblings[i] = next;
2588           break;
2589         }
2590       }
2591     }
2592
2593     Dali::Actor handle( this );
2594     mParent->mChildOrderChangedSignal.Emit( handle );
2595
2596     RequestRebuildDepthTree();
2597   }
2598   else
2599   {
2600     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
2601   }
2602 }
2603
2604 void Actor::Lower()
2605 {
2606   if ( mParent )
2607   {
2608     ActorContainer& siblings = *(mParent->mChildren);
2609     if( siblings.front() != this ) // If not already at beginning
2610     {
2611       for( std::size_t i=1; i<siblings.size(); ++i )
2612       {
2613         if( siblings[i] == this )
2614         {
2615           // Swap with previous
2616           ActorPtr previous = siblings[i-1];
2617           siblings[i-1] = this;
2618           siblings[i] = previous;
2619           break;
2620         }
2621       }
2622     }
2623
2624     Dali::Actor handle( this );
2625     mParent->mChildOrderChangedSignal.Emit( handle );
2626
2627     RequestRebuildDepthTree();
2628   }
2629   else
2630   {
2631     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
2632   }
2633 }
2634
2635 void Actor::RaiseToTop()
2636 {
2637   if ( mParent )
2638   {
2639     ActorContainer& siblings = *(mParent->mChildren);
2640     if( siblings.back() != this ) // If not already at end
2641     {
2642       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
2643       if( iter != siblings.end() )
2644       {
2645         siblings.erase(iter);
2646         siblings.push_back(ActorPtr(this));
2647       }
2648     }
2649
2650     Dali::Actor handle( this );
2651     mParent->mChildOrderChangedSignal.Emit( handle );
2652
2653     RequestRebuildDepthTree();
2654   }
2655   else
2656   {
2657     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
2658   }
2659 }
2660
2661 void Actor::LowerToBottom()
2662 {
2663   if ( mParent )
2664   {
2665     ActorContainer& siblings = *(mParent->mChildren);
2666     if( siblings.front() != this ) // If not already at bottom,
2667     {
2668       ActorPtr thisPtr(this); // ensure this actor remains referenced.
2669
2670       ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
2671       if( iter != siblings.end() )
2672       {
2673         siblings.erase(iter);
2674         siblings.insert(siblings.begin(), thisPtr);
2675       }
2676     }
2677
2678     Dali::Actor handle( this );
2679     mParent->mChildOrderChangedSignal.Emit( handle );
2680
2681     RequestRebuildDepthTree();
2682   }
2683   else
2684   {
2685     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
2686   }
2687 }
2688
2689 void Actor::RaiseAbove( Internal::Actor& target )
2690 {
2691   if ( mParent )
2692   {
2693     ActorContainer& siblings = *(mParent->mChildren);
2694     if( siblings.back() != this && target.mParent == mParent ) // If not already at top
2695     {
2696       ActorPtr thisPtr(this); // ensure this actor remains referenced.
2697
2698       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
2699       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
2700       if( thisIter < targetIter )
2701       {
2702         siblings.erase(thisIter);
2703         // Erasing early invalidates the targetIter. (Conversely, inserting first may also
2704         // invalidate thisIter)
2705         targetIter = std::find( siblings.begin(), siblings.end(), &target );
2706         ++targetIter;
2707         siblings.insert(targetIter, thisPtr);
2708       }
2709
2710       Dali::Actor handle( this );
2711       mParent->mChildOrderChangedSignal.Emit( handle );
2712
2713       RequestRebuildDepthTree();
2714     }
2715   }
2716   else
2717   {
2718     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
2719   }
2720 }
2721
2722 void Actor::LowerBelow( Internal::Actor& target )
2723 {
2724   if ( mParent )
2725   {
2726     ActorContainer& siblings = *(mParent->mChildren);
2727     if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
2728     {
2729       ActorPtr thisPtr(this); // ensure this actor remains referenced.
2730
2731       ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
2732       ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
2733
2734       if( thisIter > targetIter )
2735       {
2736         siblings.erase(thisIter); // this only invalidates iterators at or after this point.
2737         siblings.insert(targetIter, thisPtr);
2738       }
2739
2740       Dali::Actor handle( this );
2741       mParent->mChildOrderChangedSignal.Emit( handle );
2742
2743       RequestRebuildDepthTree();
2744     }
2745   }
2746   else
2747   {
2748     DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" );
2749   }
2750 }
2751
2752 void Actor::SetInheritLayoutDirection( bool inherit )
2753 {
2754   if( mInheritLayoutDirection != inherit )
2755   {
2756     mInheritLayoutDirection = inherit;
2757
2758     if( inherit && mParent )
2759     {
2760       InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
2761     }
2762   }
2763 }
2764
2765 void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
2766 {
2767   if( actor && ( actor->mInheritLayoutDirection || set ) )
2768   {
2769     if( actor->mLayoutDirection != direction )
2770     {
2771       actor->mLayoutDirection = direction;
2772       actor->EmitLayoutDirectionChangedSignal( direction );
2773       actor->RelayoutRequest();
2774     }
2775
2776     if( actor->GetChildCount() > 0 )
2777     {
2778       for( ActorPtr& child : actor->GetChildrenInternal() )
2779       {
2780         InheritLayoutDirectionRecursively( child, direction );
2781       }
2782     }
2783   }
2784 }
2785
2786 void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint )
2787 {
2788   // node is being used in a separate thread; queue a message to set the value & base value
2789   SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) );
2790 }
2791
2792 } // namespace Internal
2793
2794 } // namespace Dali