From 7f980d4fce89b03e0b5f3fe7947fa7b6e840127c Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Tue, 7 Mar 2017 12:21:08 +0000 Subject: [PATCH] Added a property to allow an actor to ignore the anchor-point for its position In that scenario, TOP_LEFT is assumed. Change-Id: Id57829b9488b0f3d3546354d51900941ca92affa --- automated-tests/src/dali/utc-Dali-Actor.cpp | 175 +++++++++++++++++++++ dali/devel-api/actors/actor-devel.h | 25 +-- dali/internal/event/actors/actor-impl.cpp | 136 +++++++++------- dali/internal/event/actors/actor-impl.h | 3 +- dali/internal/update/manager/transform-manager.cpp | 63 ++++++-- dali/internal/update/manager/transform-manager.h | 69 ++++---- dali/internal/update/nodes/node.cpp | 8 +- dali/internal/update/nodes/node.h | 24 +++ 8 files changed, 390 insertions(+), 113 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index f4d48e0..bcc2aca 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -5520,3 +5520,178 @@ int UtcDaliActorGetScreenPositionWithChildActors02(void) END_TEST; } + +int utcDaliActorPositionUsesAnchorPoint(void) +{ + TestApplication application; + tet_infoline( "Check default behaviour\n" ); + + Actor actor = Actor::New(); + actor.SetParentOrigin( ParentOrigin::CENTER ); + actor.SetAnchorPoint( AnchorPoint::CENTER ); + actor.SetSize( 100.0f, 100.0f ); + Stage::GetCurrent().Add( actor ); + + application.SendNotification(); + application.Render(); + + tet_infoline( "Check that the world position is in the center\n" ); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION ); + + tet_infoline( "Set the position uses anchor point property to false\n" ); + actor.SetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT, false ); + + application.SendNotification(); + application.Render(); + + tet_infoline( "Check that the world position has changed appropriately\n" ); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 50.0f, 50.0f, 0.0f ), TEST_LOCATION ); + + END_TEST; +} + +int utcDaliActorPositionUsesAnchorPointCheckScale(void) +{ + TestApplication application; + tet_infoline( "Check that the scale is adjusted appropriately when setting the positionUsesAnchorPoint to false\n" ); + + Actor actor = Actor::New(); + actor.SetParentOrigin( ParentOrigin::CENTER ); + actor.SetAnchorPoint( AnchorPoint::CENTER ); + actor.SetSize( 100.0f, 100.0f ); + actor.SetScale( 2.0f ); + actor.SetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT, false ); + Stage::GetCurrent().Add( actor ); + + application.SendNotification(); + application.Render(); + + tet_infoline( "Check the world position is the same as it would be without a scale\n" ); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 50.0f, 50.0f, 0.0f ), TEST_LOCATION ); + + tet_infoline( "Change the Anchor Point to TOP_LEFT and ensure the world position changes accordingly" ); + actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 100.0f, 100.0f, 0.0f ), TEST_LOCATION ); + + tet_infoline( "Change the Anchor Point to BOTTOM_RIGHT and ensure the world position changes accordingly" ); + actor.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION ); + + END_TEST; +} + +int utcDaliActorPositionUsesAnchorPointCheckRotation(void) +{ + TestApplication application; + tet_infoline( "Check that the rotation is adjusted appropriately when setting the positionUsesAnchorPoint to false\n" ); + + Actor actor = Actor::New(); + actor.SetParentOrigin( ParentOrigin::CENTER ); + actor.SetAnchorPoint( AnchorPoint::CENTER ); + actor.SetSize( 100.0f, 100.0f ); + actor.SetOrientation( Degree( 90.0f), Vector3::ZAXIS ); + actor.SetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT, false ); + Stage::GetCurrent().Add( actor ); + + application.SendNotification(); + application.Render(); + + tet_infoline( "Check the world position is the same as it would be without a rotation\n" ); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 50.0f, 50.0f, 0.0f ), TEST_LOCATION ); + + tet_infoline( "Change the Anchor Point to TOP_LEFT and ensure the world position changes accordingly" ); + actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( -50.0f, 50.0f, 0.0f ), TEST_LOCATION ); + + tet_infoline( "Change the Anchor Point to BOTTOM_RIGHT and ensure the world position changes accordingly" ); + actor.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 150.0f, 50.0f, 0.0f ), TEST_LOCATION ); + + END_TEST; +} + +int utcDaliActorPositionUsesAnchorPointCheckScaleAndRotation(void) +{ + TestApplication application; + tet_infoline( "Check that the scale and rotation is adjusted appropriately when setting the positionUsesAnchorPoint to false\n" ); + + Actor actor = Actor::New(); + actor.SetParentOrigin( ParentOrigin::CENTER ); + actor.SetAnchorPoint( AnchorPoint::CENTER ); + actor.SetSize( 100.0f, 100.0f ); + actor.SetOrientation( Degree( 90.0f), Vector3::ZAXIS ); + actor.SetScale( 2.0f ); + actor.SetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT, false ); + Stage::GetCurrent().Add( actor ); + + application.SendNotification(); + application.Render(); + + tet_infoline( "Check the world position is the same as it would be without a scale and rotation\n" ); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 50.0f, 50.0f, 0.0f ), TEST_LOCATION ); + + tet_infoline( "Change the Anchor Point to TOP_LEFT and ensure the world position changes accordingly" ); + actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( -100.0f, 100.0f, 0.0f ), TEST_LOCATION ); + + tet_infoline( "Change the Anchor Point to BOTTOM_RIGHT and ensure the world position changes accordingly" ); + actor.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), Vector3( 200.0f, 0.0f, 0.0f ), TEST_LOCATION ); + + END_TEST; +} + +int utcDaliActorPositionUsesAnchorPointOnlyInheritPosition(void) +{ + TestApplication application; + tet_infoline( "Check that if not inheriting scale and position, then the position is adjusted appropriately when setting the positionUsesAnchorPoint to false\n" ); + + Actor parent = Actor::New(); + + Stage::GetCurrent().Add( parent ); + Vector2 stageSize( Stage::GetCurrent().GetSize() ); + + Actor actor = Actor::New(); + actor.SetParentOrigin( ParentOrigin::CENTER ); + actor.SetAnchorPoint( AnchorPoint::CENTER ); + actor.SetSize( 100.0f, 100.0f ); + actor.SetInheritScale( false ); + actor.SetInheritOrientation( false ); + actor.SetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT, false ); + parent.Add( actor ); + + application.SendNotification(); + application.Render(); + + const Vector3 expectedWorldPosition( -stageSize.width * 0.5f + 50.0f, -stageSize.height * 0.5f + 50.0f, 0.0f ); + + tet_infoline( "Check the world position is in the right place\n" ); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), expectedWorldPosition, TEST_LOCATION ); + + tet_infoline( "Change the Anchor Point to TOP_LEFT and ensure world position hasn't changed" ); + actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), expectedWorldPosition, TEST_LOCATION ); + + tet_infoline( "Change the Anchor Point to BOTTOM_RIGHT and ensure world position hasn't changed" ); + actor.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentWorldPosition(), expectedWorldPosition, TEST_LOCATION ); + + END_TEST; +} + diff --git a/dali/devel-api/actors/actor-devel.h b/dali/devel-api/actors/actor-devel.h index 4d4ad78..1f0192b 100644 --- a/dali/devel-api/actors/actor-devel.h +++ b/dali/devel-api/actors/actor-devel.h @@ -88,28 +88,35 @@ enum Type CLIPPING_MODE = Dali::Actor::Property::CLIPPING_MODE, /** - * @brief name "siblingOrder", type INTEGER - * - * @details Sets the sibling order of the actor so depth position can be defined within the same parent. - * + * @brief Sets the sibling order of the actor so depth position can be defined within the same parent. + * @details Name "siblingOrder", type Property::INTEGER. + * @note The initial value is 0. * @note Raise, Lower, RaiseToTop, LowerToBottom, RaiseAbove and LowerBelow will override the - * sibling order. The values set by this Property will likey change. + * sibling order. The values set by this Property will likely change. */ - SIBLING_ORDER = CLIPPING_MODE + 1, + SIBLING_ORDER = CLIPPING_MODE + 1, /** * @brief The opacity of the actor. * @details Name "opacity", type Property::FLOAT. - * @SINCE_1_2.28 */ - OPACITY = CLIPPING_MODE + 2, + OPACITY = CLIPPING_MODE + 2, /** * @brief Returns the screen position of the Actor * @details Name "screenPosition", type Property::VECTOR2. Read-only * @note This assumes default camera and default render-task and the Z position is ZERO. */ - SCREEN_POSITION = CLIPPING_MODE + 3, + SCREEN_POSITION = CLIPPING_MODE + 3, + + /** + * @brief Determines whether the anchor point should be used to determine the position of the actor. + * @details Name "positionUsesAnchorPoint", type Property::BOOLEAN. + * @note This is true by default. + * @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 }; } // namespace Property diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index e5ed2fc..a9eddf4 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -172,63 +172,64 @@ namespace // unnamed namespace * Name Type writable animatable constraint-input enum for index-checking */ DALI_PROPERTY_TABLE_BEGIN -DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN ) -DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X ) -DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y ) -DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z ) -DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT ) -DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X ) -DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y ) -DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z ) -DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE ) -DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH ) -DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT ) -DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH ) -DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION ) -DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X ) -DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y ) -DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z ) -DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION ) -DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X ) -DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y ) -DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z ) -DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION ) -DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION ) -DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE ) -DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X ) -DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y ) -DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z ) -DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE ) -DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE ) -DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR ) -DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED ) -DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN ) -DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE ) -DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA ) -DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR ) -DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX ) -DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME ) -DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE ) -DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED ) -DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION ) -DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE ) -DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE ) -DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE ) -DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE ) -DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR ) -DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY ) -DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY ) -DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY ) -DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT ) -DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH ) -DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING ) -DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE ) -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( "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( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN ) +DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X ) +DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y ) +DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z ) +DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT ) +DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X ) +DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y ) +DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z ) +DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE ) +DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH ) +DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT ) +DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH ) +DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION ) +DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X ) +DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y ) +DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z ) +DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION ) +DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X ) +DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y ) +DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z ) +DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION ) +DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION ) +DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE ) +DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X ) +DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y ) +DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z ) +DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE ) +DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE ) +DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR ) +DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED ) +DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN ) +DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE ) +DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA ) +DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR ) +DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX ) +DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME ) +DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE ) +DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED ) +DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION ) +DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE ) +DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE ) +DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE ) +DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE ) +DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR ) +DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY ) +DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY ) +DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY ) +DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT ) +DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH ) +DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING ) +DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE ) +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( "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_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX ) // Signals @@ -2066,6 +2067,7 @@ Actor::Actor( DerivedType derivedType ) mInheritPosition( true ), mInheritOrientation( true ), mInheritScale( true ), + mPositionUsesAnchorPoint( true ), mDrawMode( DrawMode::NORMAL ), mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ), mColorMode( Node::DEFAULT_COLOR_MODE ), @@ -2765,6 +2767,20 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr break; } + case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT: + { + bool value = false; + if( property.Get( value ) && value != mPositionUsesAnchorPoint ) + { + mPositionUsesAnchorPoint = value; + if( NULL != mNode ) + { + SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint ); + } + } + break; + } + default: { // this can happen in the case of a non-animatable default property so just do nothing @@ -3307,6 +3323,12 @@ Property::Value Actor::GetDefaultProperty( Property::Index index ) const value = GetCurrentScreenPosition(); break; } + + case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT: + { + value = mPositionUsesAnchorPoint; + break; + } } return value; diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index b73371b..c9c78f9 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_ACTOR_H /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -1901,6 +1901,7 @@ protected: bool mInheritPosition : 1; ///< Cached: Whether the parent's position should be inherited. bool mInheritOrientation : 1; ///< Cached: Whether the parent's orientation should be inherited. 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. 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 diff --git a/dali/internal/update/manager/transform-manager.cpp b/dali/internal/update/manager/transform-manager.cpp index b289bf4..0d55efe 100644 --- a/dali/internal/update/manager/transform-manager.cpp +++ b/dali/internal/update/manager/transform-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -42,12 +42,41 @@ namespace static const float gDefaultTransformComponentAnimatableData[] = { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }; //Default values for anchor point (CENTER) and parent origin (TOP_LEFT) -static const float gDefaultTransformComponentStaticData[] = { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f }; +static const float gDefaultTransformComponentStaticData[] = { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, true }; DALI_COMPILE_TIME_ASSERT( sizeof(gDefaultTransformComponentAnimatableData) == sizeof(TransformComponentAnimatable) ); DALI_COMPILE_TIME_ASSERT( sizeof(gDefaultTransformComponentStaticData) == sizeof(TransformComponentStatic) ); + +/** + * @brief Calculates the center position for the transform component + * @param[out] centerPosition The calculated center-position of the transform component + * @param[in] transformComponentStatic A const reference to the static component transform struct + * @param[in] transformComponentAnimatable A const reference to the animatable component transform struct + * @param[in] size The size of the current transform component + * @param[in] half Halfway point of the transform + * @param[in] topLeft The top-left coords of the transform + */ +inline void CalculateCenterPosition( + Vector3& centerPosition, + const TransformComponentStatic& transformComponentStatic, + const TransformComponentAnimatable& transformComponentAnimatable, + const Vector3& size, + const Vector3& half, + const Vector3& topLeft ) +{ + // Calculate the center-point by applying the scale and rotation on the anchor point. + centerPosition = ( half - transformComponentStatic.mAnchorPoint ) * size * transformComponentAnimatable.mScale; + centerPosition *= transformComponentAnimatable.mOrientation; + + // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position. + if( ! transformComponentStatic.mPositionUsesAnchorPoint ) + { + centerPosition -= ( topLeft - transformComponentStatic.mAnchorPoint ) * size; + } } +} // unnamed namespace + TransformManager::TransformManager() :mComponentCount(0), mReorder(false) @@ -211,9 +240,10 @@ void TransformManager::Update() } //Iterate through all components to compute its world matrix - Vector3 anchorPosition; + Vector3 centerPosition; Vector3 localPosition; - Vector3 half( 0.5f,0.5f,0.5f ); + const Vector3 half( 0.5f,0.5f,0.5f ); + const Vector3 topLeft( 0.0f, 0.0f, 0.5f ); for( unsigned int i(0); i #include #include +#include #include namespace Dali @@ -41,10 +41,11 @@ namespace SceneGraph struct TransformComponentAnimatable { TransformComponentAnimatable() - :mScale(1.0f,1.0f,1.0f), - mOrientation(1.0f,0.0f,0.0f,0.0f), - mPosition(0.0f,0.0f,0.0f) - {} + : mScale( Vector3::ONE ), + mOrientation( Quaternion::IDENTITY ), + mPosition( Vector3::ZERO ) + { + } Vector3 mScale; Quaternion mOrientation; @@ -57,12 +58,15 @@ struct TransformComponentAnimatable struct TransformComponentStatic { TransformComponentStatic() - :mAnchorPoint(0.5f,0.5f,0.5f), - mParentOrigin(0.0f,0.0f,0.5f) - {} + : mAnchorPoint( AnchorPoint::DEFAULT ), + mParentOrigin( ParentOrigin::DEFAULT ), + mPositionUsesAnchorPoint( true ) + { + } Vector3 mAnchorPoint; Vector3 mParentOrigin; + bool mPositionUsesAnchorPoint; }; enum InheritanceMode @@ -339,6 +343,13 @@ public: */ void GetWorldMatrixAndSize( TransformId id, Matrix& worldMatrix, Vector3& size ) const; + /** + * @brief Sets the boolean which states whether the position should use the anchor-point on the given transform component. + * @param[in] id Id of the transform component + * @param[in] value True if the position should use the anchor-point + */ + void SetPositionUsesAnchorPoint( TransformId id, bool value ); + private: //Helper struct to order components @@ -363,23 +374,23 @@ private: */ void ReorderComponents(); - unsigned int mComponentCount; ///< Total number of components - FreeList mIds; ///< FreeList of Ids - Vector mTxComponentAnimatable; ///< Animatable part of the components - Vector mTxComponentStatic; ///< Static part of the components - Vector mInheritanceMode; ///< Inheritance mode of the components - Vector mComponentId; ///< Ids of the components - Vector mSize; ///< Size of the components - Vector mParent; ///< Parent of the components - Vector mWorld; ///< Local to world transform of the components - Vector mLocal; ///< Local to parent space transform of the components - Vector mBoundingSpheres; ///< Bounding spheres. xyz is the center and w is the radius - Vector mTxComponentAnimatableBaseValue; ///< Base values for the animatable part of the components - Vector mSizeBase; ///< Base value for the size of the components - Vector mComponentDirty; ///< 1u if some of the parts of the component has changed in this frame, 0 otherwise - Vector mLocalMatrixDirty; ///< 1u if the local matrix has been updated in this frame, 0 otherwise - Vector mOrderedComponents; ///< Used to reorder components when hierarchy changes - bool mReorder; ///< Flag to determine if the components have to reordered in the next Update + unsigned int mComponentCount; ///< Total number of components + FreeList mIds; ///< FreeList of Ids + Vector< TransformComponentAnimatable > mTxComponentAnimatable; ///< Animatable part of the components + Vector< TransformComponentStatic > mTxComponentStatic; ///< Static part of the components + Vector< unsigned int > mInheritanceMode; ///< Inheritance mode of the components + Vector< TransformId > mComponentId; ///< Ids of the components + Vector< Vector3 > mSize; ///< Size of the components + Vector< TransformId > mParent; ///< Parent of the components + Vector< Matrix > mWorld; ///< Local to world transform of the components + Vector< Matrix > mLocal; ///< Local to parent space transform of the components + Vector< Vector4 > mBoundingSpheres; ///< Bounding spheres. xyz is the center and w is the radius + Vector< TransformComponentAnimatable > mTxComponentAnimatableBaseValue; ///< Base values for the animatable part of the components + Vector< Vector3 > mSizeBase; ///< Base value for the size of the components + Vector< bool > mComponentDirty; ///< 1u if some of the parts of the component has changed in this frame, 0 otherwise + Vector< bool > mLocalMatrixDirty; ///< 1u if the local matrix has been updated in this frame, 0 otherwise + Vector< SOrderItem > mOrderedComponents; ///< Used to reorder components when hierarchy changes + bool mReorder; ///< Flag to determine if the components have to reordered in the next Update }; } //namespace SceneGraph @@ -390,4 +401,4 @@ private: } //namespace Dali -#endif /* TRANSFORM_MANAGER_H_ */ +#endif // DALI_INTERNAL_TRANSFORM_MANAGER_H diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index 4a3ea63..85077ac 100644 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -106,7 +106,8 @@ Node::Node() mColorMode( DEFAULT_COLOR_MODE ), mClippingMode( ClippingMode::DISABLED ), mIsRoot( false ), - mIsLayer( false ) + mIsLayer( false ), + mPositionUsesAnchorPoint( true ) { mUniformMapChanged[0] = 0u; mUniformMapChanged[1] = 0u; @@ -154,6 +155,9 @@ void Node::CreateTransform( SceneGraph::TransformManager* transformManager ) mWorldScale.Initialize( transformManager, mTransformId ); mWorldOrientation.Initialize( transformManager, mTransformId ); mWorldMatrix.Initialize( transformManager, mTransformId ); + + //Set whether the position should use the anchor point + transformManager->SetPositionUsesAnchorPoint( mTransformId, mPositionUsesAnchorPoint ); } void Node::SetRoot(bool isRoot) diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index e2ba292..dd1b79d 100644 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -716,6 +716,19 @@ public: */ unsigned int GetDepthIndex(){ return mDepthIndex; } + /** + * @brief Sets the boolean which states whether the position should use the anchor-point. + * @param[in] positionUsesAnchorPoint True if the position should use the anchor-point + */ + void SetPositionUsesAnchorPoint( bool positionUsesAnchorPoint ) + { + if( mTransformId != INVALID_TRANSFORM_ID && mPositionUsesAnchorPoint != positionUsesAnchorPoint ) + { + mPositionUsesAnchorPoint = positionUsesAnchorPoint; + mTransformManager->SetPositionUsesAnchorPoint( mTransformId, mPositionUsesAnchorPoint ); + } + } + public: /** * @copydoc UniformMap::Add @@ -865,6 +878,7 @@ protected: ClippingMode::Type mClippingMode:2; ///< The clipping mode of this node bool mIsRoot:1; ///< True if the node cannot have a parent bool mIsLayer:1; ///< True if the node is a layer + bool mPositionUsesAnchorPoint:1; ///< True if the node should use the anchor-point when calculating the position // Changes scope, should be at end of class DALI_LOG_OBJECT_STRING_DECLARATION; }; @@ -992,6 +1006,16 @@ inline void SetClippingModeMessage( EventThreadServices& eventThreadServices, co new (slot) LocalType( &node, &Node::SetClippingMode, clippingMode ); } +inline void SetPositionUsesAnchorPointMessage( EventThreadServices& eventThreadServices, const Node& node, bool positionUsesAnchorPoint ) +{ + typedef MessageValue1< Node, bool > LocalType; + + // Reserve some memory inside the message queue + unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( &node, &Node::SetPositionUsesAnchorPoint, positionUsesAnchorPoint ); +} } // namespace SceneGraph -- 2.7.4