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