From 54e52fd9d4556e19b2e97082b057ad886952e55e Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Wed, 13 Dec 2023 10:40:20 +0900 Subject: [PATCH] Add FeedTouch api to GestureDetector. This is a method of recognizing gestures by feeding a touch event to a specific actor. This causes the actor to recognize the gesture without going through a hittest. So, you can recognize gestures based on touchEvent as shown below. mTapDetector = TapGestureDetector::New(); mTapDetector.DetectedSignal().Connect(this, &HelloWorldController::OnTap); control.TouchedSignal().Connect(this, &HelloWorldController::OnTouch); bool OnTouch(Actor actor, const TouchEvent& touch) { mTapDetector.FeedTouch(actor, touch); return true; } This is the beginning of a new gesture recognition method. Change-Id: Iecf0eab7a82e54a981f69d2e309675afcfa439f1 --- .../src/dali/utc-Dali-LongPressGestureDetector.cpp | 66 +++++++++++++ .../src/dali/utc-Dali-PanGestureDetector.cpp | 82 ++++++++++++++++ .../src/dali/utc-Dali-PinchGestureDetector.cpp | 105 ++++++++++++++++++++- .../src/dali/utc-Dali-RotationGestureDetector.cpp | 104 +++++++++++++++++++- .../src/dali/utc-Dali-TapGestureDetector.cpp | 51 ++++++++++ .../event/events/gesture-detector-impl.cpp | 44 +++++++++ dali/internal/event/events/gesture-detector-impl.h | 5 + .../event/events/gesture-event-processor.cpp | 36 +++++++ .../event/events/gesture-event-processor.h | 10 ++ dali/internal/event/events/gesture-event.h | 7 ++ dali/internal/event/events/gesture-processor.cpp | 29 ++++++ dali/internal/event/events/gesture-processor.h | 20 ++++ dali/internal/event/events/gesture-recognizer.h | 34 +++++-- .../long-press-gesture-processor.cpp | 31 +++++- .../long-press-gesture-processor.h | 3 +- .../long-press-gesture-recognizer.cpp | 3 +- .../events/pan-gesture/pan-gesture-processor.cpp | 32 ++++++- .../events/pan-gesture/pan-gesture-processor.h | 3 +- .../events/pan-gesture/pan-gesture-recognizer.cpp | 3 +- .../pinch-gesture/pinch-gesture-processor.cpp | 21 ++++- .../events/pinch-gesture/pinch-gesture-processor.h | 3 +- .../pinch-gesture/pinch-gesture-recognizer.cpp | 3 +- .../rotation-gesture-processor.cpp | 22 ++++- .../rotation-gesture/rotation-gesture-processor.h | 3 +- .../rotation-gesture-recognizer.cpp | 3 +- .../events/tap-gesture/tap-gesture-processor.cpp | 42 +++++++-- .../events/tap-gesture/tap-gesture-processor.h | 3 +- .../events/tap-gesture/tap-gesture-recognizer.cpp | 3 +- dali/internal/event/events/touch-event-impl.h | 5 + dali/public-api/events/gesture-detector.cpp | 5 + dali/public-api/events/gesture-detector.h | 10 ++ 31 files changed, 751 insertions(+), 40 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp index 3ed67dd..54d5556 100644 --- a/automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp @@ -19,8 +19,11 @@ #include #include #include +#include #include #include +#include +#include #include #include #include @@ -131,6 +134,19 @@ struct TouchEventFunctor } }; +Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition, uint32_t time) +{ + Integration::TouchEvent touchEvent; + Integration::Point point; + point.SetState(state); + point.SetDeviceId(4); + point.SetScreenPosition(screenPosition); + point.SetDeviceClass(Device::Class::TOUCH); + point.SetDeviceSubclass(Device::Subclass::NONE); + touchEvent.points.push_back(point); + touchEvent.time = time; + return touchEvent; +} } // namespace /////////////////////////////////////////////////////////////////////////////// @@ -1121,3 +1137,53 @@ int UtcDaliLongPressGestureWhenGesturePropargation(void) END_TEST; } + +int UtcDaliLongPressGestureFeedTouch(void) +{ + TestApplication application; + Integration::Scene scene = application.GetScene(); + RenderTaskList taskList = scene.GetRenderTaskList(); + Dali::RenderTask task = taskList.GetTask(0); + + Actor parentActor = Actor::New(); + parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + Actor childActor = Actor::New(); + childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + parentActor.Add(childActor); + application.GetScene().Add(parentActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + SignalData pData; + GestureReceivedFunctor pFunctor(pData); + + LongPressGestureDetector parentDetector = LongPressGestureDetector::New(); + parentDetector.DetectedSignal().Connect(&application, pFunctor); + + Integration::TouchEvent tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 100); + Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100)); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->SetRenderTask(task); + Dali::TouchEvent touchEventHandle(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + TestTriggerLongPress(application); + + tp = GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 150); + touchEventImpl = new Internal::TouchEvent(150); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION); + pData.Reset(); + + END_TEST; +} diff --git a/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp index a1d4483..3206272 100644 --- a/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp @@ -19,9 +19,12 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -199,6 +202,19 @@ PanGesture GeneratePan(unsigned int time, return pan; } +Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition, uint32_t time) +{ + Integration::TouchEvent touchEvent; + Integration::Point point; + point.SetState(state); + point.SetDeviceId(4); + point.SetScreenPosition(screenPosition); + point.SetDeviceClass(Device::Class::TOUCH); + point.SetDeviceSubclass(Device::Subclass::NONE); + touchEvent.points.push_back(point); + touchEvent.time = time; + return touchEvent; +} } // namespace /////////////////////////////////////////////////////////////////////////////// @@ -3042,3 +3058,69 @@ int UtcDaliPanGestureWhenGesturePropargation(void) END_TEST; } + +int UtcDaliPanGestureFeedTouch(void) +{ + TestApplication application; + Integration::Scene scene = application.GetScene(); + RenderTaskList taskList = scene.GetRenderTaskList(); + Dali::RenderTask task = taskList.GetTask(0); + + Actor parentActor = Actor::New(); + parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + Actor childActor = Actor::New(); + childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + parentActor.Add(childActor); + application.GetScene().Add(parentActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + SignalData pData; + GestureReceivedFunctor pFunctor(pData); + + PanGestureDetector parentDetector = PanGestureDetector::New(); + parentDetector.DetectedSignal().Connect(&application, pFunctor); + + + Integration::TouchEvent tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 100); + Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100)); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->SetRenderTask(task); + Dali::TouchEvent touchEventHandle(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + + tp = GenerateSingleTouch(PointState::MOTION, Vector2(70.0f, 70.0f), 150); + touchEventImpl = new Internal::TouchEvent(150); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + + tp = GenerateSingleTouch(PointState::MOTION, Vector2(90.0f, 90.0f), 200); + touchEventImpl = new Internal::TouchEvent(200); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateSingleTouch(PointState::UP, Vector2(100.0f, 100.0f), 250); + touchEventImpl = new Internal::TouchEvent(250); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + + DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION); + pData.Reset(); + + END_TEST; +} diff --git a/automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp index 2c45979..2937a40 100644 --- a/automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp @@ -18,7 +18,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -113,6 +116,23 @@ struct UnstageActorFunctor : public GestureReceivedFunctor Integration::Scene scene; }; + +Integration::TouchEvent GenerateDoubleTouch(PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time) +{ + Integration::TouchEvent touchEvent; + Integration::Point point; + point.SetState(stateA); + point.SetScreenPosition(screenPositionA); + point.SetDeviceClass(Device::Class::TOUCH); + point.SetDeviceSubclass(Device::Subclass::NONE); + touchEvent.points.push_back(point); + point.SetScreenPosition(screenPositionB); + point.SetState(stateB); + touchEvent.points.push_back(point); + touchEvent.time = time; + return touchEvent; +} + } // namespace /////////////////////////////////////////////////////////////////////////////// @@ -1205,4 +1225,87 @@ int UtcDaliPinchGestureWhenGesturePropargation(void) pData.Reset(); END_TEST; -} \ No newline at end of file +} + +int UtcDaliPinchGestureFeedTouch(void) +{ + TestApplication application; + Integration::Scene scene = application.GetScene(); + RenderTaskList taskList = scene.GetRenderTaskList(); + Dali::RenderTask task = taskList.GetTask(0); + + Actor parentActor = Actor::New(); + parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + Actor childActor = Actor::New(); + childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + parentActor.Add(childActor); + application.GetScene().Add(parentActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + SignalData pData; + GestureReceivedFunctor pFunctor(pData); + + PinchGestureDetector parentDetector = PinchGestureDetector::New(); + parentDetector.DetectedSignal().Connect(&application, pFunctor); + + Integration::TouchEvent tp = GenerateDoubleTouch(PointState::DOWN, Vector2(2.0f, 20.0f), PointState::DOWN, Vector2(38.0f, 20.0f), 100); + Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100)); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + Dali::TouchEvent touchEventHandle(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 150); + touchEventImpl = new Internal::TouchEvent(150); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 200); + touchEventImpl = new Internal::TouchEvent(200); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 250); + touchEventImpl = new Internal::TouchEvent(250); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 300); + touchEventImpl = new Internal::TouchEvent(300); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::UP, Vector2(10.0f, 20.0f), PointState::UP, Vector2(30.0f, 20.0f), 350); + touchEventImpl = new Internal::TouchEvent(350); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + + DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION); + pData.Reset(); + + END_TEST; +} diff --git a/automated-tests/src/dali/utc-Dali-RotationGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-RotationGestureDetector.cpp index 8c1d929..6b5b333 100644 --- a/automated-tests/src/dali/utc-Dali-RotationGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-RotationGestureDetector.cpp @@ -18,7 +18,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -113,6 +116,21 @@ struct UnstageActorFunctor : public GestureReceivedFunctor Integration::Scene scene; }; +Integration::TouchEvent GenerateDoubleTouch(PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time) +{ + Integration::TouchEvent touchEvent; + Integration::Point point; + point.SetState(stateA); + point.SetScreenPosition(screenPositionA); + point.SetDeviceClass(Device::Class::TOUCH); + point.SetDeviceSubclass(Device::Subclass::NONE); + touchEvent.points.push_back(point); + point.SetScreenPosition(screenPositionB); + point.SetState(stateB); + touchEvent.points.push_back(point); + touchEvent.time = time; + return touchEvent; +} } // namespace /////////////////////////////////////////////////////////////////////////////// @@ -1171,4 +1189,88 @@ int UtcDaliRotationGestureWhenGesturePropargation(void) pData.Reset(); END_TEST; -} \ No newline at end of file +} + + +int UtcDaliRotationGestureFeedTouch(void) +{ + TestApplication application; + Integration::Scene scene = application.GetScene(); + RenderTaskList taskList = scene.GetRenderTaskList(); + Dali::RenderTask task = taskList.GetTask(0); + + Actor parentActor = Actor::New(); + parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + Actor childActor = Actor::New(); + childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + parentActor.Add(childActor); + application.GetScene().Add(parentActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + SignalData pData; + GestureReceivedFunctor pFunctor(pData); + + RotationGestureDetector parentDetector = RotationGestureDetector::New(); + parentDetector.DetectedSignal().Connect(&application, pFunctor); + + Integration::TouchEvent tp = GenerateDoubleTouch(PointState::DOWN, Vector2(2.0f, 20.0f), PointState::DOWN, Vector2(38.0f, 20.0f), 100); + Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100)); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + Dali::TouchEvent touchEventHandle(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 150); + touchEventImpl = new Internal::TouchEvent(150); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 200); + touchEventImpl = new Internal::TouchEvent(200); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 250); + touchEventImpl = new Internal::TouchEvent(250); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::MOTION, Vector2(6.0f, 6.0f), PointState::MOTION, Vector2(18.0f, 18.0f), 300); + touchEventImpl = new Internal::TouchEvent(300); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateDoubleTouch(PointState::UP, Vector2(10.0f, 8.0f), PointState::UP, Vector2(14.0f, 16.0f), 350); + touchEventImpl = new Internal::TouchEvent(350); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->AddPoint(tp.GetPoint(1)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + + DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION); + pData.Reset(); + + END_TEST; +} diff --git a/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp index 5c15b92..09f176f 100644 --- a/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp @@ -18,7 +18,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -1331,3 +1334,51 @@ int UtcDaliTapGestureDetectorCheck(void) END_TEST; } + +int UtcDaliTapGestureFeedTouch(void) +{ + TestApplication application; + Integration::Scene scene = application.GetScene(); + RenderTaskList taskList = scene.GetRenderTaskList(); + Dali::RenderTask task = taskList.GetTask(0); + + Actor parentActor = Actor::New(); + parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + Actor childActor = Actor::New(); + childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + + parentActor.Add(childActor); + application.GetScene().Add(parentActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + SignalData pData; + GestureReceivedFunctor pFunctor(pData); + + TapGestureDetector parentDetector = TapGestureDetector::New(); + parentDetector.DetectedSignal().Connect(&application, pFunctor); + + Integration::TouchEvent tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 1, 100); + Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100)); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->SetRenderTask(task); + Dali::TouchEvent touchEventHandle(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + tp = GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 1, 150); + touchEventImpl = new Internal::TouchEvent(150); + touchEventImpl->AddPoint(tp.GetPoint(0)); + touchEventImpl->SetRenderTask(task); + touchEventHandle = Dali::TouchEvent(touchEventImpl.Get()); + parentDetector.FeedTouch(parentActor, touchEventHandle); + + DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION); + pData.Reset(); + + END_TEST; +} diff --git a/dali/internal/event/events/gesture-detector-impl.cpp b/dali/internal/event/events/gesture-detector-impl.cpp index b3b8981..dfa343f 100644 --- a/dali/internal/event/events/gesture-detector-impl.cpp +++ b/dali/internal/event/events/gesture-detector-impl.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include namespace Dali { @@ -257,6 +259,48 @@ Dali::Actor GestureDetector::GetAttachedActor(size_t index) const return actor; } +bool GestureDetector::FeedTouch(Dali::Actor& actor, Dali::TouchEvent& touch) +{ + bool ret = false; + if(touch.GetPointCount() > 0) + { + const PointState::Type state = touch.GetState(0); + Dali::Internal::Actor& actorImpl(GetImplementation(actor)); + if(state == PointState::DOWN) + { + Attach(actorImpl); + } + + Integration::TouchEvent touchEvent(touch.GetTime()); + for(std::size_t i = 0; i< touch.GetPointCount(); i++) + { + Integration::Point point; + point.SetState(touch.GetState(i)); + point.SetDeviceId(touch.GetDeviceId(i)); + point.SetScreenPosition(touch.GetScreenPosition(i)); + point.SetRadius(touch.GetRadius(i)); + point.SetPressure(touch.GetPressure(i)); + point.SetAngle(touch.GetAngle(i)); + point.SetDeviceClass(touch.GetDeviceClass(i)); + point.SetDeviceSubclass(touch.GetDeviceSubclass(i)); + point.SetMouseButton(touch.GetMouseButton(i)); + point.SetHitActor(touch.GetHitActor(i)); + point.SetLocalPosition(touch.GetLocalPosition(i)); + touchEvent.points.push_back(point); + } + + Dali::Internal::TouchEvent& touchEventImpl(GetImplementation(touch)); + mGestureEventProcessor.ProcessTouchEvent(this, actorImpl, GetImplementation(touchEventImpl.GetRenderTaskPtr()), actorImpl.GetScene(), touchEvent); + + if(state == PointState::FINISHED || state == PointState::INTERRUPTED || state == PointState::LEAVE) + { + Detach(actorImpl); + } + ret = true; + } + return ret; +} + bool GestureDetector::IsAttached(Actor& actor) const { return (find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor) != mPendingAttachActors.end()) || diff --git a/dali/internal/event/events/gesture-detector-impl.h b/dali/internal/event/events/gesture-detector-impl.h index dd312e6..1a4ecaa 100644 --- a/dali/internal/event/events/gesture-detector-impl.h +++ b/dali/internal/event/events/gesture-detector-impl.h @@ -83,6 +83,11 @@ public: Dali::Actor GetAttachedActor(size_t index) const; /** + * @copydoc Dali::GestureDetector::FeedTouch() + */ + bool FeedTouch(Dali::Actor& actor, Dali::TouchEvent& touch); + + /** * Returns a const reference to the container of attached actor pointers. * @return A const reference to the attached internal actors. */ diff --git a/dali/internal/event/events/gesture-event-processor.cpp b/dali/internal/event/events/gesture-event-processor.cpp index 99dd285..a45500a 100644 --- a/dali/internal/event/events/gesture-event-processor.cpp +++ b/dali/internal/event/events/gesture-event-processor.cpp @@ -57,6 +57,42 @@ void GestureEventProcessor::ProcessTouchEvent(Scene& scene, const Integration::T mRotationGestureProcessor.ProcessTouch(scene, event); } +void GestureEventProcessor::ProcessTouchEvent(GestureDetector* gestureDetector, Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event) +{ + switch(gestureDetector->GetType()) + { + case GestureType::LONG_PRESS: + { + mLongPressGestureProcessor.ProcessTouch(actor, renderTask, scene, event); + break; + } + + case GestureType::PAN: + { + mPanGestureProcessor.ProcessTouch(actor, renderTask, scene, event); + break; + } + + case GestureType::PINCH: + { + mPinchGestureProcessor.ProcessTouch(actor, renderTask, scene, event); + break; + } + + case GestureType::TAP: + { + mTapGestureProcessor.ProcessTouch(actor, renderTask, scene, event); + break; + } + + case GestureType::ROTATION: + { + mRotationGestureProcessor.ProcessTouch(actor, renderTask, scene, event); + break; + } + } +} + void GestureEventProcessor::AddGestureDetector(GestureDetector* gestureDetector, Scene& scene) { switch(gestureDetector->GetType()) diff --git a/dali/internal/event/events/gesture-event-processor.h b/dali/internal/event/events/gesture-event-processor.h index 212b6bf..30d7836 100644 --- a/dali/internal/event/events/gesture-event-processor.h +++ b/dali/internal/event/events/gesture-event-processor.h @@ -74,6 +74,16 @@ public: // To be called by EventProcessor */ void ProcessTouchEvent(Scene& scene, const Integration::TouchEvent& event); + /** + * This function is called by gesture detector whenever a touch event occurs + * @param[in] gestureDetector The gesture detector + * @param[in] actor The actor + * @param[in] renderTask The renderTask + * @param[in] scene The scene + * @param[in] event The event that has occurred + */ + void ProcessTouchEvent(GestureDetector* gestureDetector, Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event); + public: // To be called by gesture detectors /** * This method adds the specified gesture detector to the relevant gesture processor. diff --git a/dali/internal/event/events/gesture-event.h b/dali/internal/event/events/gesture-event.h index d803dcf..87b4cb4 100644 --- a/dali/internal/event/events/gesture-event.h +++ b/dali/internal/event/events/gesture-event.h @@ -21,6 +21,7 @@ // INTERNAL INCLUDES #include #include +#include namespace Dali { @@ -66,6 +67,12 @@ struct GestureEvent */ GestureSourceData sourceData; + /** + * The render task used to generate this touch event. + */ + RenderTaskPtr renderTask; + + protected: // Constructors only to be used by derived structures. /** * This constructor is only used by derived classes. diff --git a/dali/internal/event/events/gesture-processor.cpp b/dali/internal/event/events/gesture-processor.cpp index a2d581c..2a3c538 100644 --- a/dali/internal/event/events/gesture-processor.cpp +++ b/dali/internal/event/events/gesture-processor.cpp @@ -100,6 +100,19 @@ void GestureProcessor::ProcessTouch(Scene& scene, const Integration::TouchEvent& } } +void GestureProcessor::ProcessTouch(Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event) +{ + if(mGestureRecognizer) + { + if(!event.points.empty()) + { + mPoint = event.points[0]; + mEventTime = event.time; + } + mGestureRecognizer->SendEvent(actor, renderTask, scene, event); + } +} + void GestureProcessor::GetGesturedActor(Actor*& actor, GestureDetectorContainer& gestureDetectors) { while(actor) @@ -201,6 +214,22 @@ void GestureProcessor::ProcessAndEmit(HitTestAlgorithm::Results& hitTestResults) } } +void GestureProcessor::ProcessAndEmitActor(HitTestAlgorithm::Results& hitTestResults) +{ + if(hitTestResults.actor) + { + Actor* hitTestActor(&GetImplementation(hitTestResults.actor)); + Actor* actor(hitTestActor); + GestureDetectorContainer gestureDetectors; + GetGesturedActor(actor, gestureDetectors); + + if(actor && actor->IsVisible() && !gestureDetectors.empty() && actor == hitTestActor) + { + EmitGestureSignal(actor, gestureDetectors, hitTestResults.actorCoordinates); + } + } +} + bool GestureProcessor::HitTest(Scene& scene, Vector2 screenCoordinates, HitTestAlgorithm::Results& hitTestResults) { GestureHitTestCheck hitCheck(mType); diff --git a/dali/internal/event/events/gesture-processor.h b/dali/internal/event/events/gesture-processor.h index e2015f3..4c8491b 100644 --- a/dali/internal/event/events/gesture-processor.h +++ b/dali/internal/event/events/gesture-processor.h @@ -44,6 +44,15 @@ public: void ProcessTouch(Scene& scene, const Integration::TouchEvent& event); /** + * Process the touch event in the attached recognizer + * @param[in] actor The actor which gesture want to recognize. + * @param[in] renderTask RenderTask. + * @param[in] scene Scene. + * @param[in] event Touch event to process + */ + void ProcessTouch(Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event); + + /** * Returns whether any GestureDetector requires a Core::Update * @return true if update required */ @@ -92,6 +101,17 @@ protected: void ProcessAndEmit(HitTestAlgorithm::Results& hitTestResults); /** + * Calls the emission method in the deriving class for actor + * + * @param[in] hitTestResults The Hit Test Results. + * + * @note Uses the CheckGestureDetector() to check if the gesture matches the criteria of the given gesture detector + * and EmitGestureSignal() to emit the signal. + * @pre Hit Testing should already be done. + */ + void ProcessAndEmitActor(HitTestAlgorithm::Results& hitTestResults); + + /** * Hit test the screen coordinates, and place the results in hitTestResults. * @param[in] scene Scene. * @param[in] screenCoordinates The screen coordinates to test. diff --git a/dali/internal/event/events/gesture-recognizer.h b/dali/internal/event/events/gesture-recognizer.h index 0bc013d..498879e 100644 --- a/dali/internal/event/events/gesture-recognizer.h +++ b/dali/internal/event/events/gesture-recognizer.h @@ -20,7 +20,9 @@ // EXTERNAL INCLUDES #include +#include #include +#include #include #include #include @@ -42,7 +44,7 @@ template class RecognizerObserver { public: - virtual void Process(Scene& scene, const T& event) = 0; + virtual void Process(Scene& scene, const T& event, Actor* actor = nullptr) = 0; virtual ~RecognizerObserver() = default; ; @@ -130,6 +132,20 @@ public: SendEvent(event); } + /** + * Called when we get a touch event. + * @param[in] actor The actor the touch event has occurred on + * @param[in] renderTask The renderTask the touch event has occurred on + * @param[in] scene The scene the touch event has occurred on + * @param[in] event The latest touch event + */ + void SendEvent(Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event) + { + mActor.SetActor(&actor); + mRenderTask = &renderTask; + SendEvent(scene, event); + } + protected: /** * Protected Constructor. Should only be able to create derived class objects. @@ -141,7 +157,9 @@ protected: mType(detectorType), mScene(nullptr), mSourceType(GestureSourceType::INVALID), - mSourceData(GestureSourceData::INVALID) + mSourceData(GestureSourceData::INVALID), + mActor(), + mRenderTask() { } @@ -162,11 +180,13 @@ protected: ~GestureRecognizer() override = default; protected: - Vector2 mScreenSize; - GestureType::Value mType; - Scene* mScene; - GestureSourceType mSourceType; /// < Gesture input source type. - GestureSourceData mSourceData; /// < Gesture input source data. + Vector2 mScreenSize; + GestureType::Value mType; + Scene* mScene; + GestureSourceType mSourceType; /// < Gesture input source type. + GestureSourceData mSourceData; /// < Gesture input source data. + ActorObserver mActor; /// < The actor used to generate this touch event. + RenderTaskPtr mRenderTask; /// < The render task used to generate this touch event. }; using GestureRecognizerPtr = IntrusivePtr; diff --git a/dali/internal/event/events/long-press-gesture/long-press-gesture-processor.cpp b/dali/internal/event/events/long-press-gesture/long-press-gesture-processor.cpp index 6b680ae..a2cc919 100644 --- a/dali/internal/event/events/long-press-gesture/long-press-gesture-processor.cpp +++ b/dali/internal/event/events/long-press-gesture/long-press-gesture-processor.cpp @@ -124,7 +124,7 @@ LongPressGestureProcessor::LongPressGestureProcessor() LongPressGestureProcessor::~LongPressGestureProcessor() = default; -void LongPressGestureProcessor::Process(Scene& scene, const LongPressGestureEvent& longPressEvent) +void LongPressGestureProcessor::Process(Scene& scene, const LongPressGestureEvent& longPressEvent, Actor* actor) { DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_LONG_PRESS_GESTURE"); switch(longPressEvent.state) @@ -135,7 +135,11 @@ void LongPressGestureProcessor::Process(Scene& scene, const LongPressGestureEven ResetActor(); HitTestAlgorithm::Results hitTestResults; - if(HitTest(scene, longPressEvent.point, hitTestResults)) + if(actor) + { + SetActor(actor); + } + else if(HitTest(scene, longPressEvent.point, hitTestResults)) { SetActor(&GetImplementation(hitTestResults.actor)); } @@ -148,7 +152,19 @@ void LongPressGestureProcessor::Process(Scene& scene, const LongPressGestureEven if(currentGesturedActor) { HitTestAlgorithm::Results hitTestResults; - HitTest(scene, longPressEvent.point, hitTestResults); + if(actor) + { + hitTestResults.actor = Dali::Actor(actor); + hitTestResults.renderTask = longPressEvent.renderTask; + + Vector2 actorCoords; + currentGesturedActor->ScreenToLocal(*hitTestResults.renderTask.Get(), actorCoords.x, actorCoords.y, longPressEvent.point.x, longPressEvent.point.y); + hitTestResults.actorCoordinates = actorCoords; + } + else + { + HitTest(scene, longPressEvent.point, hitTestResults); + } if(hitTestResults.actor && (currentGesturedActor == &GetImplementation(hitTestResults.actor))) { @@ -157,7 +173,14 @@ void LongPressGestureProcessor::Process(Scene& scene, const LongPressGestureEven // Set mCurrentLongPressEvent to use inside overridden methods called from ProcessAndEmit() mCurrentLongPressEvent = &longPressEvent; - ProcessAndEmit(hitTestResults); + if(actor) + { + ProcessAndEmitActor(hitTestResults); + } + else + { + ProcessAndEmit(hitTestResults); + } mCurrentLongPressEvent = nullptr; } else diff --git a/dali/internal/event/events/long-press-gesture/long-press-gesture-processor.h b/dali/internal/event/events/long-press-gesture/long-press-gesture-processor.h index 0543748..b3d1437 100644 --- a/dali/internal/event/events/long-press-gesture/long-press-gesture-processor.h +++ b/dali/internal/event/events/long-press-gesture/long-press-gesture-processor.h @@ -58,8 +58,9 @@ public: // To be called by GestureEventProcessor * This method is called whenever a long press gesture event occurs. * @param[in] scene The scene the long press gesture event occurs in. * @param[in] longPressEvent The event that has occurred. + * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest. */ - void Process(Scene& scene, const LongPressGestureEvent& longPressEvent) override; + void Process(Scene& scene, const LongPressGestureEvent& longPressEvent, Actor* actor = nullptr) override; /** * Adds a gesture detector to this gesture processor. diff --git a/dali/internal/event/events/long-press-gesture/long-press-gesture-recognizer.cpp b/dali/internal/event/events/long-press-gesture/long-press-gesture-recognizer.cpp index eac654b..93aad44 100644 --- a/dali/internal/event/events/long-press-gesture/long-press-gesture-recognizer.cpp +++ b/dali/internal/event/events/long-press-gesture/long-press-gesture-recognizer.cpp @@ -241,13 +241,14 @@ void LongPressGestureRecognizer::EmitGesture(GestureState state) } longPress.sourceType = mSourceType; longPress.sourceData = mSourceData; + longPress.renderTask = mRenderTask; if(mScene) { // Create another handle so the recognizer cannot be destroyed during process function GestureRecognizerPtr recognizerHandle = this; - mObserver.Process(*mScene, longPress); + mObserver.Process(*mScene, longPress, mActor.GetActor()); } } } diff --git a/dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp b/dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp index eaaff7a..3a471d3 100644 --- a/dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp +++ b/dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp @@ -143,7 +143,7 @@ PanGestureProcessor::~PanGestureProcessor() mSceneObject = nullptr; // mSceneObject is owned and destroyed by update manager (there is only one of these for now) } -void PanGestureProcessor::Process(Scene& scene, const PanGestureEvent& panEvent) +void PanGestureProcessor::Process(Scene& scene, const PanGestureEvent& panEvent, Actor* actor) { #if defined(DEBUG_ENABLED) DALI_LOG_TRACE_METHOD(gLogFilter); @@ -163,7 +163,12 @@ void PanGestureProcessor::Process(Scene& scene, const PanGestureEvent& panEvent) ResetActor(); HitTestAlgorithm::Results hitTestResults; - if(HitTest(scene, panEvent.currentPosition, hitTestResults)) + if(actor) + { + SetActor(actor); + mPossiblePanPosition = panEvent.currentPosition; + } + else if(HitTest(scene, panEvent.currentPosition, hitTestResults)) { SetActor(&GetImplementation(hitTestResults.actor)); mPossiblePanPosition = panEvent.currentPosition; @@ -180,7 +185,19 @@ void PanGestureProcessor::Process(Scene& scene, const PanGestureEvent& panEvent) // it can be told when the gesture ends as well. HitTestAlgorithm::Results hitTestResults; - HitTest(scene, panEvent.previousPosition, hitTestResults); // Hit Test previous position + if(actor) + { + hitTestResults.actor = Dali::Actor(actor); + hitTestResults.renderTask = panEvent.renderTask; + + Vector2 actorCoords; + actor->ScreenToLocal(*hitTestResults.renderTask.Get(), actorCoords.x, actorCoords.y, panEvent.currentPosition.x, panEvent.currentPosition.y); + hitTestResults.actorCoordinates = actorCoords; + } + else + { + HitTest(scene, panEvent.previousPosition, hitTestResults); // Hit Test previous position + } if(hitTestResults.actor) { @@ -196,7 +213,14 @@ void PanGestureProcessor::Process(Scene& scene, const PanGestureEvent& panEvent) // Set mCurrentPanEvent to use inside overridden methods called in ProcessAndEmit() mCurrentPanEvent = &panEvent; - ProcessAndEmit(hitTestResults); + if(actor) + { + ProcessAndEmitActor(hitTestResults); + } + else + { + ProcessAndEmit(hitTestResults); + } mCurrentPanEvent = nullptr; } else diff --git a/dali/internal/event/events/pan-gesture/pan-gesture-processor.h b/dali/internal/event/events/pan-gesture/pan-gesture-processor.h index bfeb623..4209c24 100644 --- a/dali/internal/event/events/pan-gesture/pan-gesture-processor.h +++ b/dali/internal/event/events/pan-gesture/pan-gesture-processor.h @@ -67,8 +67,9 @@ public: // To be called by GestureEventProcessor * This method is called whenever a pan gesture event occurs. * @param[in] scene The scene the pan gesture event occurs in. * @param[in] panEvent The event that has occurred. + * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest. */ - void Process(Scene& scene, const PanGestureEvent& panEvent) override; + void Process(Scene& scene, const PanGestureEvent& panEvent, Actor* actor = nullptr) override; /** * Adds a gesture detector to this gesture processor. diff --git a/dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp b/dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp index 4e6ad9e..4e7af02 100644 --- a/dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp +++ b/dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp @@ -335,13 +335,14 @@ void PanGestureRecognizer::SendPan(GestureState state, const Integration::TouchE gesture.time = currentEvent.time; gesture.sourceType = mSourceType; gesture.sourceData = mSourceData; + gesture.renderTask = mRenderTask; if(mScene) { // Create another handle so the recognizer cannot be destroyed during process function GestureRecognizerPtr recognizerHandle = this; - mObserver.Process(*mScene, gesture); + mObserver.Process(*mScene, gesture, mActor.GetActor()); } } diff --git a/dali/internal/event/events/pinch-gesture/pinch-gesture-processor.cpp b/dali/internal/event/events/pinch-gesture/pinch-gesture-processor.cpp index 73e8dcd..7f25011 100644 --- a/dali/internal/event/events/pinch-gesture/pinch-gesture-processor.cpp +++ b/dali/internal/event/events/pinch-gesture/pinch-gesture-processor.cpp @@ -175,7 +175,7 @@ void PinchGestureProcessor::SetMinimumTouchEventsAfterStart(uint32_t value) } } -void PinchGestureProcessor::Process(Scene& scene, const PinchGestureEvent& pinchEvent) +void PinchGestureProcessor::Process(Scene& scene, const PinchGestureEvent& pinchEvent, Actor* actor) { DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_PINCH_GESTURE"); switch(pinchEvent.state) @@ -189,7 +189,24 @@ void PinchGestureProcessor::Process(Scene& scene, const PinchGestureEvent& pinch ResetActor(); HitTestAlgorithm::Results hitTestResults; - if(HitTest(scene, pinchEvent.centerPoint, hitTestResults)) + if(actor) + { + hitTestResults.actor = Dali::Actor(actor); + hitTestResults.renderTask = pinchEvent.renderTask; + + // Record the current render-task for Screen->Actor coordinate conversions + mCurrentRenderTask = hitTestResults.renderTask; + + Vector2 actorCoords; + actor->ScreenToLocal(*mCurrentRenderTask.Get(), actorCoords.x, actorCoords.y, pinchEvent.centerPoint.x, pinchEvent.centerPoint.y); + hitTestResults.actorCoordinates = actorCoords; + + // Set mCurrentPinchEvent to use inside overridden methods called from ProcessAndEmit() + mCurrentPinchEvent = &pinchEvent; + ProcessAndEmitActor(hitTestResults); + mCurrentPinchEvent = nullptr; + } + else if(HitTest(scene, pinchEvent.centerPoint, hitTestResults)) { // Record the current render-task for Screen->Actor coordinate conversions mCurrentRenderTask = hitTestResults.renderTask; diff --git a/dali/internal/event/events/pinch-gesture/pinch-gesture-processor.h b/dali/internal/event/events/pinch-gesture/pinch-gesture-processor.h index 9d7acf0..e5f71d7 100644 --- a/dali/internal/event/events/pinch-gesture/pinch-gesture-processor.h +++ b/dali/internal/event/events/pinch-gesture/pinch-gesture-processor.h @@ -78,8 +78,9 @@ public: // To be called by GestureEventProcessor * This method is called whenever a pinch gesture event occurs. * @param[in] scene The scene the pinch gesture event occurs in. * @param[in] pinchEvent The event that has occurred. + * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest. */ - void Process(Scene& scene, const PinchGestureEvent& pinchEvent) override; + void Process(Scene& scene, const PinchGestureEvent& pinchEvent, Actor* actor = nullptr) override; /** * Adds a gesture detector to this gesture processor. diff --git a/dali/internal/event/events/pinch-gesture/pinch-gesture-recognizer.cpp b/dali/internal/event/events/pinch-gesture/pinch-gesture-recognizer.cpp index 9ab75a2..49df4ae 100644 --- a/dali/internal/event/events/pinch-gesture/pinch-gesture-recognizer.cpp +++ b/dali/internal/event/events/pinch-gesture/pinch-gesture-recognizer.cpp @@ -262,13 +262,14 @@ void PinchGestureRecognizer::SendPinch(GestureState state, const Integration::To gesture.time = currentEvent.time; gesture.sourceType = mSourceType; gesture.sourceData = mSourceData; + gesture.renderTask = mRenderTask; if(mScene) { // Create another handle so the recognizer cannot be destroyed during process function GestureRecognizerPtr recognizerHandle = this; - mObserver.Process(*mScene, gesture); + mObserver.Process(*mScene, gesture, mActor.GetActor()); } } diff --git a/dali/internal/event/events/rotation-gesture/rotation-gesture-processor.cpp b/dali/internal/event/events/rotation-gesture/rotation-gesture-processor.cpp index a83b1b2..111e7c1 100644 --- a/dali/internal/event/events/rotation-gesture/rotation-gesture-processor.cpp +++ b/dali/internal/event/events/rotation-gesture/rotation-gesture-processor.cpp @@ -121,7 +121,7 @@ RotationGestureProcessor::RotationGestureProcessor() { } -void RotationGestureProcessor::Process(Scene& scene, const RotationGestureEvent& rotationEvent) +void RotationGestureProcessor::Process(Scene& scene, const RotationGestureEvent& rotationEvent, Actor* actor) { DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_ROTATION_GESTURE"); switch(rotationEvent.state) @@ -135,7 +135,25 @@ void RotationGestureProcessor::Process(Scene& scene, const RotationGestureEvent& ResetActor(); HitTestAlgorithm::Results hitTestResults; - if(HitTest(scene, rotationEvent.centerPoint, hitTestResults)) + if(actor) + { + hitTestResults.actor = Dali::Actor(actor); + hitTestResults.renderTask = rotationEvent.renderTask; + + // Record the current render-task for Screen->Actor coordinate conversions + mCurrentRenderTask = hitTestResults.renderTask; + + Vector2 actorCoords; + actor->ScreenToLocal(*mCurrentRenderTask.Get(), actorCoords.x, actorCoords.y, rotationEvent.centerPoint.x, rotationEvent.centerPoint.y); + hitTestResults.actorCoordinates = actorCoords; + + // Set mCurrentRotationEvent to use inside overridden methods called from ProcessAndEmit() + mCurrentRotationEvent = &rotationEvent; + ProcessAndEmitActor(hitTestResults); + mCurrentRotationEvent = nullptr; + + } + else if(HitTest(scene, rotationEvent.centerPoint, hitTestResults)) { // Record the current render-task for Screen->Actor coordinate conversions mCurrentRenderTask = hitTestResults.renderTask; diff --git a/dali/internal/event/events/rotation-gesture/rotation-gesture-processor.h b/dali/internal/event/events/rotation-gesture/rotation-gesture-processor.h index f1459bc..b1d1fa7 100644 --- a/dali/internal/event/events/rotation-gesture/rotation-gesture-processor.h +++ b/dali/internal/event/events/rotation-gesture/rotation-gesture-processor.h @@ -63,8 +63,9 @@ public: // To be called by GestureEventProcessor * This method is called whenever a rotation gesture event occurs. * @param[in] scene The scene the rotation gesture event occurs in. * @param[in] rotationEvent The event that has occurred. + * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest. */ - void Process(Scene& scene, const RotationGestureEvent& rotationEvent) override; + void Process(Scene& scene, const RotationGestureEvent& rotationEvent, Actor* actor = nullptr) override; /** * Adds a gesture detector to this gesture processor. diff --git a/dali/internal/event/events/rotation-gesture/rotation-gesture-recognizer.cpp b/dali/internal/event/events/rotation-gesture/rotation-gesture-recognizer.cpp index dc10844..37aa79a 100644 --- a/dali/internal/event/events/rotation-gesture/rotation-gesture-recognizer.cpp +++ b/dali/internal/event/events/rotation-gesture/rotation-gesture-recognizer.cpp @@ -224,13 +224,14 @@ void RotationGestureRecognizer::SendRotation(GestureState state, const Integrati gesture.time = currentEvent.time; gesture.sourceType = mSourceType; gesture.sourceData = mSourceData; + gesture.renderTask = mRenderTask; if(mScene) { // Create another handle so the recognizer cannot be destroyed during process function GestureRecognizerPtr recognizerHandle = this; - mObserver.Process(*mScene, gesture); + mObserver.Process(*mScene, gesture, mActor.GetActor()); } } diff --git a/dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp b/dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp index bb4cfa7..0f1418a 100644 --- a/dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp +++ b/dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp @@ -100,7 +100,7 @@ TapGestureProcessor::TapGestureProcessor() TapGestureProcessor::~TapGestureProcessor() = default; -void TapGestureProcessor::Process(Scene& scene, const TapGestureEvent& tapEvent) +void TapGestureProcessor::Process(Scene& scene, const TapGestureEvent& tapEvent, Actor* actor) { DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_TAP_GESTURE"); switch(tapEvent.state) @@ -109,7 +109,15 @@ void TapGestureProcessor::Process(Scene& scene, const TapGestureEvent& tapEvent) { // Do a hit test and if an actor has been hit then save to see if tap event is still valid on a tap( same actor being hit ) HitTestAlgorithm::Results hitTestResults; - if(HitTest(scene, tapEvent.point, hitTestResults)) + if(actor) + { + SetActor(actor); + mCurrentTapActor.SetActor(GetCurrentGesturedActor()); + + // Indicate that we've processed a touch down. Bool should be sufficient as a change in actor will result in a cancellation + mPossibleProcessed = true; + } + else if(HitTest(scene, tapEvent.point, hitTestResults)) { SetActor(&GetImplementation(hitTestResults.actor)); mCurrentTapActor.SetActor(GetCurrentGesturedActor()); @@ -128,16 +136,32 @@ void TapGestureProcessor::Process(Scene& scene, const TapGestureEvent& tapEvent) { // Ensure that we're processing a hit on the current actor and that we've already processed a touch down HitTestAlgorithm::Results hitTestResults; - if(GetCurrentGesturedActor() && HitTest(scene, tapEvent.point, hitTestResults) && mPossibleProcessed) + if(GetCurrentGesturedActor()) { - // Check that this actor is still the one that was used for the last touch down ? - if(mCurrentTapActor.GetActor() == &GetImplementation(hitTestResults.actor)) + if(actor) + { + hitTestResults.actor = Dali::Actor(actor); + hitTestResults.renderTask = tapEvent.renderTask; + // Check that this actor is still the one that was used for the last touch down ? + if(mCurrentTapActor.GetActor() == &GetImplementation(hitTestResults.actor)) + { + mCurrentTapEvent = &tapEvent; + ProcessAndEmitActor(hitTestResults); + } + mCurrentTapEvent = nullptr; + mPossibleProcessed = false; + } + else if(HitTest(scene, tapEvent.point, hitTestResults) && mPossibleProcessed) { - mCurrentTapEvent = &tapEvent; - ProcessAndEmit(hitTestResults); + // Check that this actor is still the one that was used for the last touch down ? + if(mCurrentTapActor.GetActor() == &GetImplementation(hitTestResults.actor)) + { + mCurrentTapEvent = &tapEvent; + ProcessAndEmit(hitTestResults); + } + mCurrentTapEvent = nullptr; + mPossibleProcessed = false; } - mCurrentTapEvent = nullptr; - mPossibleProcessed = false; } break; } diff --git a/dali/internal/event/events/tap-gesture/tap-gesture-processor.h b/dali/internal/event/events/tap-gesture/tap-gesture-processor.h index 6b1ab28..b5f8a27 100644 --- a/dali/internal/event/events/tap-gesture/tap-gesture-processor.h +++ b/dali/internal/event/events/tap-gesture/tap-gesture-processor.h @@ -59,8 +59,9 @@ public: // To be called by GestureEventProcessor * This method is called whenever a tap gesture event occurs. * @param[in] scene The scene the tap gesture event occurs in. * @param[in] tapEvent The event that has occurred. + * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest. */ - void Process(Scene& scene, const TapGestureEvent& event) override; + void Process(Scene& scene, const TapGestureEvent& event, Actor* actor = nullptr) override; /** * Adds a gesture detector to this gesture processor. diff --git a/dali/internal/event/events/tap-gesture/tap-gesture-recognizer.cpp b/dali/internal/event/events/tap-gesture/tap-gesture-recognizer.cpp index cfa5d72..b59ccb2 100644 --- a/dali/internal/event/events/tap-gesture/tap-gesture-recognizer.cpp +++ b/dali/internal/event/events/tap-gesture/tap-gesture-recognizer.cpp @@ -219,11 +219,12 @@ void TapGestureRecognizer::ProcessEvent(TapGestureEvent& event) { event.sourceType = mSourceType; event.sourceData = mSourceData; + event.renderTask = mRenderTask; if(mScene) { // Create another handle so the recognizer cannot be destroyed during process function GestureRecognizerPtr recognizerHandle = this; - mObserver.Process(*mScene, event); + mObserver.Process(*mScene, event, mActor.GetActor()); } } diff --git a/dali/internal/event/events/touch-event-impl.h b/dali/internal/event/events/touch-event-impl.h index e59c597..e645c75 100644 --- a/dali/internal/event/events/touch-event-impl.h +++ b/dali/internal/event/events/touch-event-impl.h @@ -183,6 +183,11 @@ public: return mRenderTask; } + Dali::RenderTask& GetRenderTaskPtr() + { + return mRenderTask; + } + // Setters /** diff --git a/dali/public-api/events/gesture-detector.cpp b/dali/public-api/events/gesture-detector.cpp index d1d6d0e..a9cc55a 100644 --- a/dali/public-api/events/gesture-detector.cpp +++ b/dali/public-api/events/gesture-detector.cpp @@ -70,4 +70,9 @@ Actor GestureDetector::GetAttachedActor(size_t index) const return GetImplementation(*this).GetAttachedActor(index); } +bool GestureDetector::FeedTouch(Dali::Actor& actor, Dali::TouchEvent& touch) +{ + return GetImplementation(*this).FeedTouch(actor, touch); +} + } // namespace Dali diff --git a/dali/public-api/events/gesture-detector.h b/dali/public-api/events/gesture-detector.h index 432d9bc..e94959d 100644 --- a/dali/public-api/events/gesture-detector.h +++ b/dali/public-api/events/gesture-detector.h @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include namespace Dali { @@ -164,6 +165,15 @@ public: // Actor related */ Actor GetAttachedActor(size_t index) const; + /** + * @brief The gesture is recognized by sending a Touch event to the actor. + * + * @param actor The actor receiving touch events + * @param touch The thouch event + * @return If true , the gesture is being recognized. + */ + bool FeedTouch(Dali::Actor& actor, Dali::TouchEvent& touch); + protected: /// @cond internal /** -- 2.7.4