From 199a66447fc65d87cdfffc39465253ddcb0e436b Mon Sep 17 00:00:00 2001 From: Joogab Yun Date: Tue, 20 Oct 2020 15:46:19 +0900 Subject: [PATCH] Add TouchDelegateArea property. TouchDelegateArea can reset the actor's touchable area. This is usefull when the actor is small, but it should have a larger touch area. for example Actor actor = Actor::New(); actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Vector2(200.0f, 200.0f)); actor.TouchedSignal().Connect(OnTouchCallback); The actor is small, If you want to set the touch area to a larger area, you can use the TOUCH_DELEGATE_AREA property. Change-Id: Ic4e3683e09d1636bc61719ea1e83bcd05a1c4153 --- automated-tests/src/dali/utc-Dali-Actor.cpp | 37 +++++++++++++ .../src/dali/utc-Dali-TouchProcessing.cpp | 63 ++++++++++++++++++++++ dali/devel-api/actors/actor-devel.h | 16 +++++- dali/internal/event/actors/actor-impl.cpp | 2 + dali/internal/event/actors/actor-impl.h | 20 +++++++ .../event/actors/actor-property-handler.cpp | 17 ++++++ dali/internal/event/events/ray-test.cpp | 2 +- 7 files changed, 155 insertions(+), 2 deletions(-) mode change 100644 => 100755 automated-tests/src/dali/utc-Dali-Actor.cpp mode change 100644 => 100755 dali/internal/event/actors/actor-property-handler.cpp mode change 100644 => 100755 dali/internal/event/events/ray-test.cpp diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp old mode 100644 new mode 100755 index 0b2a35b..d161892 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -7926,6 +7926,43 @@ int UtcDaliActorCaptureAllTouchAfterStartPropertyN(void) END_TEST; } +int UtcDaliActorTouchDelegateAreaPropertyP(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + Vector2 touchDelegateArea = actor.GetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA).Get(); + DALI_TEST_EQUALS(touchDelegateArea, Vector2::ZERO, TEST_LOCATION); + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Vector2(10.f, 10.f)); + touchDelegateArea = actor.GetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA).Get(); + DALI_TEST_EQUALS(touchDelegateArea, Vector2(10.f, 10.f), TEST_LOCATION); + END_TEST; +} + +int UtcDaliActorTouchDelegateAreaPropertyN(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Make sure setting invalid types does not cause a crash + try + { + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, 1.0f); + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Vector2::ONE); + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Vector3::ONE); + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Vector4::ONE); + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Property::Map()); + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Property::Array()); + tet_result(TET_PASS); + } + catch(...) + { + tet_result(TET_FAIL); + } + END_TEST; +} + int UtcDaliActorLowerBelowNegative(void) { TestApplication application; diff --git a/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp b/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp index 3c01346..e0c7b80 100755 --- a/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp +++ b/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp @@ -2121,3 +2121,66 @@ int UtcDaliTouchEventIntercept(void) END_TEST; } +int UtcDaliTouchDelegateArea(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + application.GetScene().Add(actor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Connect to actor's touched signal + SignalData data; + TouchEventFunctor functor(data, false /* Do not consume */); + actor.TouchedSignal().Connect(&application, functor); + + // Emit a down signal + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(110.0f, 110.0f))); + // The actor touched signal is not called because the touch area is outside actor. + DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION); + data.Reset(); + + // set a bigger touch delegate area + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Vector2(200.0f, 200.0f)); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Emit a down signal + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(110.0f, 110.0f))); + // The actor touched signal is called because the touch area is inside touchDelegateArea. + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION); + DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor); + data.Reset(); + + // set a smaller touch delegate area + actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Vector2(50.0f, 50.0f)); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Emit a down signal + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(80.0f, 80.0f))); + // The actor touched signal is not called because the touch area is outside touchDelegateArea. + DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION); + data.Reset(); + + // Emit a down signal + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(30.0f, 30.0f))); + // The actor touched signal is called because the touch area is inside touchDelegateArea. + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION); + DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor); + data.Reset(); + + END_TEST; +} diff --git a/dali/devel-api/actors/actor-devel.h b/dali/devel-api/actors/actor-devel.h index cda374f..7b1b7d1 100755 --- a/dali/devel-api/actors/actor-devel.h +++ b/dali/devel-api/actors/actor-devel.h @@ -117,7 +117,21 @@ enum Type * @details Name "captureAllTouchAfterStart", type Property::BOOLEAN * @note Default is false, i.e. actor under touch event will receive the touch even if touch started on this actor */ - CAPTURE_ALL_TOUCH_AFTER_START + CAPTURE_ALL_TOUCH_AFTER_START, + + /** + * @brief If you set the TOUCH_DELEGATE_AREA on an actor, when you touch the actor, the delegate area is used rather than the size of the actor + * @details Name "touchDelegateArea", type Property::Vector2 + * @note Default is Vector2::ZERO. + * @note for example + * Actor actor = Actor::New(); + * actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); + * actor.SetProperty(DevelActor::Property::TOUCH_DELEGATE_AREA, Vector2(200.0f, 200.0f)); + * actor.TouchedSignal().Connect(OnTouchCallback); + * + * If you want to reset the touch area to an area different with the size of the actor, you can set this TOUCH_DELEGATE_AREA property. + */ + TOUCH_DELEGATE_AREA }; } // namespace Property diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 4fdf0c2..75ca77c 100755 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -143,6 +143,7 @@ DALI_PROPERTY( "keyboardFocusable", BOOLEAN, true, false, false, Dali: DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER ) DALI_PROPERTY( "updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT ) DALI_PROPERTY( "captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START ) +DALI_PROPERTY( "touchDelegateArea", VECTOR2, true, false, false, Dali::DevelActor::Property::TOUCH_DELEGATE_AREA ) DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties ) // Signals @@ -1451,6 +1452,7 @@ Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node ) mTargetPosition( Vector3::ZERO ), mTargetScale( Vector3::ONE ), mAnimatedSize( Vector3::ZERO ), + mTouchDelegateArea( Vector2::ZERO ), mName(), mSortedDepth( 0u ), mDepth( 0u ), diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index a982904..4404718 100755 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -1382,6 +1382,25 @@ public: return mCaptureAllTouchAfterStart; } + /** + * Sets the touch delegate area of an actor. + * @param [in] area The new area. + */ + void SetTouchDelegateArea(Vector2 area) + { + mTouchDelegateArea = area; + } + + /** + * Retrieve the Actor's touch delegate area. + * @return The Actor's touch delegate area. + */ + const Vector2& GetTouchDelegateArea() const + { + return mTouchDelegateArea; + } + + // Gestures /** @@ -2026,6 +2045,7 @@ protected: Vector3 mTargetPosition; ///< Event-side storage for position (not a pointer as most actors will have a position) Vector3 mTargetScale; ///< Event-side storage for scale Vector3 mAnimatedSize; ///< Event-side storage for size animation + Vector2 mTouchDelegateArea; ///< touch delegate area std::string mName; ///< Name of the actor uint32_t mSortedDepth; ///< The sorted depth index. A combination of tree traversal and sibling order. diff --git a/dali/internal/event/actors/actor-property-handler.cpp b/dali/internal/event/actors/actor-property-handler.cpp old mode 100644 new mode 100755 index 099466e..415f637 --- a/dali/internal/event/actors/actor-property-handler.cpp +++ b/dali/internal/event/actors/actor-property-handler.cpp @@ -574,6 +574,17 @@ void Actor::PropertyHandler::SetDefaultProperty( Internal::Actor& actor, Propert break; } + case Dali::DevelActor::Property::TOUCH_DELEGATE_AREA: + { + Vector2 vec2Value; + if( property.Get( vec2Value ) ) + { + actor.SetTouchDelegateArea( vec2Value ); + } + break; + } + + default: { // this can happen in the case of a non-animatable default property so just do nothing @@ -1603,6 +1614,12 @@ bool Actor::PropertyHandler::GetCachedPropertyValue(const Internal::Actor& actor break; } + case Dali::DevelActor::Property::TOUCH_DELEGATE_AREA: + { + value = actor.GetTouchDelegateArea(); + break; + } + default: { // Must be a scene-graph only property diff --git a/dali/internal/event/events/ray-test.cpp b/dali/internal/event/events/ray-test.cpp old mode 100644 new mode 100755 index cee959d..112c03a --- a/dali/internal/event/events/ray-test.cpp +++ b/dali/internal/event/events/ray-test.cpp @@ -156,7 +156,7 @@ bool RayTest::ActorTest(const Internal::Actor& actor, const Vector4& rayOrigin, // Ray travels distance * rayDirLocal to intersect with plane. distance = a / b; - const Vector3& size = node.GetSize(EventThreadServices::Get().GetEventBufferIndex()); + const Vector2& size = actor.GetTouchDelegateArea() == Vector2::ZERO ? Vector2(node.GetSize(EventThreadServices::Get().GetEventBufferIndex())) : actor.GetTouchDelegateArea(); hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f; hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f; -- 2.7.4