Added property of layout direction for RTL/LTR support 40/144140/11
authortaeyoon0.lee <taeyoon0.lee@samsung.com>
Mon, 14 Aug 2017 15:42:10 +0000 (00:42 +0900)
committertaeyoon0.lee <taeyoon0.lee@samsung.com>
Fri, 18 Aug 2017 05:39:14 +0000 (14:39 +0900)
Change-Id: I515ef33ca7501731706a199c06030457a4e8c289

automated-tests/src/dali/utc-Dali-Actor.cpp
dali/devel-api/actors/actor-devel.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h

index 0fa0347..bb9d9a4 100644 (file)
@@ -6120,3 +6120,79 @@ int utcDaliActorVisibilityChangeSignalAfterAnimation(void)
 
   END_TEST;
 }
+
+int UtcDaliActorLayoutDirectionProperty(void)
+{
+  TestApplication application;
+  tet_infoline( "Check layout direction property" );
+
+  Actor actor0 = Actor::New();
+  DALI_TEST_EQUALS( actor0.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Stage::GetCurrent().Add( actor0 );
+
+  application.SendNotification();
+  application.Render();
+
+  Actor actor1 = Actor::New();
+  DALI_TEST_EQUALS( actor1.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Actor actor2 = Actor::New();
+  DALI_TEST_EQUALS( actor2.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Actor actor3 = Actor::New();
+  DALI_TEST_EQUALS( actor3.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Actor actor4 = Actor::New();
+  DALI_TEST_EQUALS( actor4.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Actor actor5 = Actor::New();
+  DALI_TEST_EQUALS( actor5.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Actor actor6 = Actor::New();
+  DALI_TEST_EQUALS( actor6.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Actor actor7 = Actor::New();
+  DALI_TEST_EQUALS( actor7.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Actor actor8 = Actor::New();
+  DALI_TEST_EQUALS( actor8.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  Actor actor9 = Actor::New();
+  DALI_TEST_EQUALS( actor9.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+
+  actor1.Add( actor2 );
+  actor1.SetProperty( DevelActor::Property::LAYOUT_DIRECTION, "RTL" );
+  DALI_TEST_EQUALS( actor1.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor2.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+
+  actor0.Add( actor1 );
+  DALI_TEST_EQUALS( actor1.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor2.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+
+  Stage::GetCurrent().Add( actor3 );
+  actor3.Add( actor4 );
+  actor4.Add( actor5 );
+  actor5.Add( actor6 );
+  actor5.Add( actor7 );
+  actor7.Add( actor8 );
+  actor8.Add( actor9 );
+  actor3.SetProperty( DevelActor::Property::LAYOUT_DIRECTION, "RTL" );
+  actor5.SetProperty( DevelActor::Property::LAYOUT_DIRECTION, "LTR" );
+
+  DALI_TEST_EQUALS( actor8.GetProperty< bool >( DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE ), true, TEST_LOCATION );
+  actor8.SetProperty( DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE, false );
+  DALI_TEST_EQUALS( actor8.GetProperty< bool >( DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE ), false, TEST_LOCATION );
+
+  actor7.SetProperty( DevelActor::Property::LAYOUT_DIRECTION, "RTL" );
+
+  DALI_TEST_EQUALS( actor3.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor4.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor5.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor6.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor7.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor8.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor9.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+
+  actor8.SetProperty( DevelActor::Property::LAYOUT_DIRECTION, "RTL" );
+  DALI_TEST_EQUALS( actor8.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor9.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+
+  actor7.SetProperty( DevelActor::Property::LAYOUT_DIRECTION, "LTR" );
+  DALI_TEST_EQUALS( actor7.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "LTR", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor8.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor9.GetProperty< std::string >( DevelActor::Property::LAYOUT_DIRECTION ), "RTL", TEST_LOCATION );
+
+  END_TEST;
+}
index 58d0d5d..1c23a46 100644 (file)
@@ -116,7 +116,19 @@ enum Type
    * @note If false, then the top-left of the actor is used for the position.
    * @note Setting this to false will allow scaling or rotation around the anchor-point without affecting the actor's position.
    */
-  POSITION_USES_ANCHOR_POINT = CLIPPING_MODE + 4
+  POSITION_USES_ANCHOR_POINT = CLIPPING_MODE + 4,
+
+  /**
+   * @brief The direction of layout.
+   * @details Name "layoutDirection", type Property::STRING.
+   */
+  LAYOUT_DIRECTION = CLIPPING_MODE + 5,
+
+  /**
+   * @brief Determines whether child actors inherit the layout direction from a parent.
+   * @details Name "layoutDirectionInheritance", type Property::BOOLEAN.
+   */
+  LAYOUT_DIRECTION_INHERITANCE = CLIPPING_MODE + 6
 };
 
 } // namespace Property
@@ -132,6 +144,17 @@ enum Type
 
 } // namespace VisibilityChange
 
+namespace LayoutDirection
+{
+
+enum Type
+{
+  LTR,   ///< Left to Right direction (Default).
+  RTL    ///< Right to Left direction.
+};
+
+} // namespace
+
 typedef Signal< void ( Actor, bool, VisibilityChange::Type ) > VisibilityChangedSignalType; ///< Signal type of VisibilityChangedSignal
 
 /**
index ea7fe9f..ff11642 100644 (file)
@@ -212,6 +212,8 @@ DALI_PROPERTY( "siblingOrder",              INTEGER,  true,  false, false, Dali:
 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
@@ -307,6 +309,10 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
 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_TABLE_END( LAYOUT_DIRECTION )
 
 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
 {
@@ -489,6 +495,8 @@ void Actor::Add( Actor& child )
       // Notification for derived classes
       OnChildAdd( child );
 
+      InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
+
       // Only put in a relayout request if there is a suitable dependency
       if( RelayoutDependentOnChildren() )
       {
@@ -2102,6 +2110,8 @@ Actor::Actor( DerivedType derivedType )
   mInheritScale( true ),
   mPositionUsesAnchorPoint( true ),
   mVisible( true ),
+  mLayoutDirectionInheritance( true ),
+  mLayoutDirection( DevelActor::LayoutDirection::LTR ),
   mDrawMode( DrawMode::NORMAL ),
   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
   mColorMode( Node::DEFAULT_COLOR_MODE ),
@@ -2860,6 +2870,31 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
       break;
     }
 
+    case Dali::DevelActor::Property::LAYOUT_DIRECTION:
+    {
+      Dali::DevelActor::LayoutDirection::Type direction = mLayoutDirection;
+      bool flag = false;
+
+      if( Scripting::GetEnumerationProperty< DevelActor::LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
+      {
+        flag = mLayoutDirectionInheritance;
+        mLayoutDirectionInheritance = true;
+        InheritLayoutDirectionRecursively( this, direction );
+        mLayoutDirectionInheritance = flag;
+      }
+      break;
+    }
+
+    case Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE:
+    {
+      bool value = false;
+      if( property.Get( value ) && value != mLayoutDirectionInheritance )
+      {
+        mLayoutDirectionInheritance = value;
+      }
+      break;
+    }
+
     default:
     {
       // this can happen in the case of a non-animatable default property so just do nothing
@@ -4102,6 +4137,18 @@ bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& valu
       break;
     }
 
+    case Dali::DevelActor::Property::LAYOUT_DIRECTION:
+    {
+      value = Scripting::GetLinearEnumerationName< DevelActor::LayoutDirection::Type >( mLayoutDirection, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT );
+      break;
+    }
+
+    case Dali::DevelActor::Property::LAYOUT_DIRECTION_INHERITANCE:
+    {
+      value = mLayoutDirectionInheritance;
+      break;
+    }
+
     default:
     {
       // Must be a scene-graph only property
@@ -5272,6 +5319,28 @@ void Actor::LowerBelow( Internal::Actor& target )
   }
 }
 
+void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::DevelActor::LayoutDirection::Type direction )
+{
+  if( actor && actor->mLayoutDirectionInheritance )
+  {
+    if( actor->mLayoutDirection != direction)
+    {
+      actor->mLayoutDirection = direction;
+      actor->RelayoutRequest();
+    }
+
+    if( actor->GetChildCount() > 0 )
+    {
+      ActorContainer& children = actor->GetChildrenInternal();
+      for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
+      {
+        InheritLayoutDirectionRecursively( *iter, direction );
+      }
+    }
+  }
+
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 2f73da5..feef540 100644 (file)
@@ -1909,6 +1909,13 @@ private:
    */
   void SetVisibleInternal( bool visible, SendMessage::Type sendMessage );
 
+  /**
+   * @brief Propagates layout direction recursively.
+   * @param[in] actor The actor for seting layout direction.
+   * @param[in] direction New layout direction.
+   */
+  void InheritLayoutDirectionRecursively( ActorPtr actor, Dali::DevelActor::LayoutDirection::Type direction );
+
 protected:
 
   Actor* mParent;                 ///< Each actor (except the root) can have one parent
@@ -1963,6 +1970,8 @@ protected:
   bool mInheritScale                               : 1; ///< Cached: Whether the parent's scale should be inherited.
   bool mPositionUsesAnchorPoint                    : 1; ///< Cached: Whether the position uses the anchor point or not.
   bool mVisible                                    : 1; ///< Cached: Whether the actor is visible or not.
+  bool mLayoutDirectionInheritance                 : 1; ///< Whether the actor inherits the layout direction from parent.
+  DevelActor::LayoutDirection::Type mLayoutDirection  : 1; ///< Layout direction, Left to Right or Right to Left.
   DrawMode::Type mDrawMode                         : 2; ///< Cached: How the actor and its children should be drawn
   PositionInheritanceMode mPositionInheritanceMode : 2; ///< Cached: Determines how position is inherited
   ColorMode mColorMode                             : 2; ///< Cached: Determines whether mWorldColor is inherited