From 2a4f0c63a4971e253a11dfb9af74d8880b4e2184 Mon Sep 17 00:00:00 2001 From: "taeyoon0.lee" Date: Tue, 15 Aug 2017 00:42:10 +0900 Subject: [PATCH] Added property of layout direction for RTL/LTR support Change-Id: I515ef33ca7501731706a199c06030457a4e8c289 --- automated-tests/src/dali/utc-Dali-Actor.cpp | 76 +++++++++++++++++++++++++++++ dali/devel-api/actors/actor-devel.h | 25 +++++++++- dali/internal/event/actors/actor-impl.cpp | 69 ++++++++++++++++++++++++++ dali/internal/event/actors/actor-impl.h | 9 ++++ 4 files changed, 178 insertions(+), 1 deletion(-) diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index 0fa0347..bb9d9a4 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -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; +} diff --git a/dali/devel-api/actors/actor-devel.h b/dali/devel-api/actors/actor-devel.h index 58d0d5d..1c23a46 100644 --- a/dali/devel-api/actors/actor-devel.h +++ b/dali/devel-api/actors/actor-devel.h @@ -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 /** diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index ea7fe9f..ff11642 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -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 diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index 2f73da5..feef540 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -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 -- 2.7.4