Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
index ff11642..5428e97 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,7 +33,6 @@
 #include <dali/public-api/math/radian.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/devel-api/actors/actor-devel.h>
-#include <dali/devel-api/object/weak-handle.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/internal/common/internal-constants.h>
 #include <dali/internal/event/common/event-thread-services.h>
@@ -208,12 +207,12 @@ DALI_PROPERTY( "minimumSize",               VECTOR2,  true,  false, false, Dali:
 DALI_PROPERTY( "maximumSize",               VECTOR2,  true,  false, false, Dali::Actor::Property::MAXIMUM_SIZE )
 DALI_PROPERTY( "inheritPosition",           BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_POSITION )
 DALI_PROPERTY( "clippingMode",              STRING,   true,  false, false, Dali::Actor::Property::CLIPPING_MODE )
+DALI_PROPERTY( "layoutDirection",           STRING,   true,  false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
+DALI_PROPERTY( "inheritLayoutDirection",    BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
 DALI_PROPERTY( "siblingOrder",              INTEGER,  true,  false, false, Dali::DevelActor::Property::SIBLING_ORDER )
 DALI_PROPERTY( "opacity",                   FLOAT,    true,  true,  true,  Dali::DevelActor::Property::OPACITY )
 DALI_PROPERTY( "screenPosition",            VECTOR2,  false, false, false, Dali::DevelActor::Property::SCREEN_POSITION )
 DALI_PROPERTY( "positionUsesAnchorPoint",   BOOLEAN,  true,  false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
-DALI_PROPERTY( "layoutDirection",           STRING,  true,  false, false, Dali::DevelActor::Property::LAYOUT_DIRECTION )
-DALI_PROPERTY( "layoutDirectionInheritance",    BOOLEAN,  true,  false, false, Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE )
 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
 
 // Signals
@@ -225,6 +224,10 @@ const char* const SIGNAL_ON_STAGE = "onStage";
 const char* const SIGNAL_OFF_STAGE = "offStage";
 const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
 const char* const SIGNAL_TOUCH = "touch";
+const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
+const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
+const char* const SIGNAL_CHILD_ADDED = "childAdded";
+const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
 
 // Actions
 
@@ -245,6 +248,10 @@ SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectS
 SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
 SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
 SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &Actor::DoConnectSignal );
+SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
+SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
+SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
+SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
 
 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
@@ -310,8 +317,8 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
 
 DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
-DALI_ENUM_TO_STRING_WITH_SCOPE( DevelActor::LayoutDirection, LTR )
-DALI_ENUM_TO_STRING_WITH_SCOPE( DevelActor::LayoutDirection, RTL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
 DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
 
 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
@@ -474,7 +481,7 @@ void Actor::Add( Actor& child )
     // if we already have parent, unparent us first
     if( oldParent )
     {
-      oldParent->Remove( child ); // This causes OnChildRemove callback
+      oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal
 
       // Old parent may need to readjust to missing child
       if( oldParent->RelayoutDependentOnChildren() )
@@ -494,6 +501,7 @@ void Actor::Add( Actor& child )
 
       // Notification for derived classes
       OnChildAdd( child );
+      EmitChildAddedSignal( child );
 
       InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
 
@@ -548,6 +556,7 @@ void Actor::Remove( Actor& child )
 
   // Notification for derived classes
   OnChildRemove( child );
+  EmitChildRemovedSignal( child );
 }
 
 void Actor::Unparent()
@@ -815,11 +824,14 @@ const Vector3& Actor::GetCurrentWorldPosition() const
 
 const Vector2 Actor::GetCurrentScreenPosition() const
 {
-  if( OnStage() && NULL != mNode )
+  StagePtr stage = Stage::GetCurrent();
+  if( stage && OnStage() && NULL != mNode )
   {
-    StagePtr stage = Stage::GetCurrent();
     Vector3 worldPosition =  mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
-    Vector3 actorSize = GetCurrentSize() * GetCurrentScale();
+    Vector3 cameraPosition = stage->GetDefaultCameraActor().mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
+    worldPosition -= cameraPosition;
+
+    Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
     Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage
     Vector3 halfActorSize( actorSize * 0.5f );
     Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
@@ -1994,6 +2006,33 @@ void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityCha
   }
 }
 
+void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
+{
+  if( ! mLayoutDirectionChangedSignal.Empty() )
+  {
+    Dali::Actor handle( this );
+    mLayoutDirectionChangedSignal.Emit( handle, type );
+  }
+}
+
+void Actor::EmitChildAddedSignal( Actor& child )
+{
+  if( ! mChildAddedSignal.Empty() )
+  {
+    Dali::Actor handle( &child );
+    mChildAddedSignal.Emit( handle );
+  }
+}
+
+void Actor::EmitChildRemovedSignal( Actor& child )
+{
+  if( ! mChildRemovedSignal.Empty() )
+  {
+    Dali::Actor handle( &child );
+    mChildRemovedSignal.Emit( handle );
+  }
+}
+
 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
 {
   return mTouchedSignal;
@@ -2034,6 +2073,21 @@ DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
   return mVisibilityChangedSignal;
 }
 
+Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
+{
+  return mLayoutDirectionChangedSignal;
+}
+
+DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
+{
+  return mChildAddedSignal;
+}
+
+DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
+{
+  return mChildRemovedSignal;
+}
+
 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
 {
   bool connected( true );
@@ -2067,6 +2121,22 @@ bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
   {
     actor->TouchSignal().Connect( tracker, functor );
   }
+  else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
+  {
+    actor->VisibilityChangedSignal().Connect( tracker, functor );
+  }
+  else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
+  {
+    actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
+  }
+  else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
+  {
+    actor->ChildAddedSignal().Connect( tracker, functor );
+  }
+  else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
+  {
+    actor->ChildRemovedSignal().Connect( tracker, functor );
+  }
   else
   {
     // signalName does not match any signal
@@ -2085,6 +2155,17 @@ Actor::Actor( DerivedType derivedType )
   mAnchorPoint( NULL ),
   mRelayoutData( NULL ),
   mGestureData( NULL ),
+  mTouchedSignal(),
+  mTouchSignal(),
+  mHoveredSignal(),
+  mWheelEventSignal(),
+  mOnStageSignal(),
+  mOffStageSignal(),
+  mOnRelayoutSignal(),
+  mVisibilityChangedSignal(),
+  mLayoutDirectionChangedSignal(),
+  mChildAddedSignal(),
+  mChildRemovedSignal(),
   mTargetOrientation( Quaternion::IDENTITY ),
   mTargetColor( Color::WHITE ),
   mTargetSize( Vector3::ZERO ),
@@ -2110,8 +2191,8 @@ Actor::Actor( DerivedType derivedType )
   mInheritScale( true ),
   mPositionUsesAnchorPoint( true ),
   mVisible( true ),
-  mLayoutDirectionInheritance( true ),
-  mLayoutDirection( DevelActor::LayoutDirection::LTR ),
+  mInheritLayoutDirection( true ),
+  mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
   mDrawMode( DrawMode::NORMAL ),
   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
   mColorMode( Node::DEFAULT_COLOR_MODE ),
@@ -2870,27 +2951,24 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
       break;
     }
 
-    case Dali::DevelActor::Property::LAYOUT_DIRECTION:
+    case Dali::Actor::Property::LAYOUT_DIRECTION:
     {
-      Dali::DevelActor::LayoutDirection::Type direction = mLayoutDirection;
-      bool flag = false;
+      Dali::LayoutDirection::Type direction = mLayoutDirection;
+      mInheritLayoutDirection = false;
 
-      if( Scripting::GetEnumerationProperty< DevelActor::LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
+      if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
       {
-        flag = mLayoutDirectionInheritance;
-        mLayoutDirectionInheritance = true;
-        InheritLayoutDirectionRecursively( this, direction );
-        mLayoutDirectionInheritance = flag;
+        InheritLayoutDirectionRecursively( this, direction, true );
       }
       break;
     }
 
-    case Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE:
+    case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
     {
       bool value = false;
-      if( property.Get( value ) && value != mLayoutDirectionInheritance )
+      if( property.Get( value ) )
       {
-        mLayoutDirectionInheritance = value;
+        SetInheritLayoutDirection( value );
       }
       break;
     }
@@ -4137,15 +4215,15 @@ bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& valu
       break;
     }
 
-    case Dali::DevelActor::Property::LAYOUT_DIRECTION:
+    case Dali::Actor::Property::LAYOUT_DIRECTION:
     {
-      value = Scripting::GetLinearEnumerationName< DevelActor::LayoutDirection::Type >( mLayoutDirection, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT );
+      value = mLayoutDirection;
       break;
     }
 
-    case Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE:
+    case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
     {
-      value = mLayoutDirectionInheritance;
+      value = IsLayoutDirectionInherited();
       break;
     }
 
@@ -5198,7 +5276,7 @@ void Actor::Lower()
     ActorContainer& siblings = *(mParent->mChildren);
     if( siblings.front() != this ) // If not already at beginning
     {
-      for( size_t i=0; i<siblings.size(); ++i )
+      for( size_t i=1; i<siblings.size(); ++i )
       {
         if( siblings[i] == this )
         {
@@ -5319,13 +5397,32 @@ void Actor::LowerBelow( Internal::Actor& target )
   }
 }
 
-void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::DevelActor::LayoutDirection::Type direction )
+void Actor::SetInheritLayoutDirection( bool inherit )
 {
-  if( actor && actor->mLayoutDirectionInheritance )
+  if( mInheritLayoutDirection != inherit )
+  {
+    mInheritLayoutDirection = inherit;
+
+    if( inherit && mParent )
+    {
+      InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
+    }
+  }
+}
+
+bool Actor::IsLayoutDirectionInherited() const
+{
+  return mInheritLayoutDirection;
+}
+
+void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
+{
+  if( actor && ( actor->mInheritLayoutDirection || set ) )
   {
     if( actor->mLayoutDirection != direction)
     {
       actor->mLayoutDirection = direction;
+      actor->EmitLayoutDirectionChangedSignal( direction );
       actor->RelayoutRequest();
     }
 
@@ -5338,7 +5435,6 @@ void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::DevelActor:
       }
     }
   }
-
 }
 
 } // namespace Internal