Add FeedTouch api to GestureDetector. 33/302733/24
authorjoogab.yun <joogab.yun@samsung.com>
Wed, 13 Dec 2023 01:40:20 +0000 (10:40 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Thu, 4 Jan 2024 08:04:30 +0000 (17:04 +0900)
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

31 files changed:
automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp
automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp
automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp
automated-tests/src/dali/utc-Dali-RotationGestureDetector.cpp
automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp
dali/internal/event/events/gesture-detector-impl.cpp
dali/internal/event/events/gesture-detector-impl.h
dali/internal/event/events/gesture-event-processor.cpp
dali/internal/event/events/gesture-event-processor.h
dali/internal/event/events/gesture-event.h
dali/internal/event/events/gesture-processor.cpp
dali/internal/event/events/gesture-processor.h
dali/internal/event/events/gesture-recognizer.h
dali/internal/event/events/long-press-gesture/long-press-gesture-processor.cpp
dali/internal/event/events/long-press-gesture/long-press-gesture-processor.h
dali/internal/event/events/long-press-gesture/long-press-gesture-recognizer.cpp
dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp
dali/internal/event/events/pan-gesture/pan-gesture-processor.h
dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp
dali/internal/event/events/pinch-gesture/pinch-gesture-processor.cpp
dali/internal/event/events/pinch-gesture/pinch-gesture-processor.h
dali/internal/event/events/pinch-gesture/pinch-gesture-recognizer.cpp
dali/internal/event/events/rotation-gesture/rotation-gesture-processor.cpp
dali/internal/event/events/rotation-gesture/rotation-gesture-processor.h
dali/internal/event/events/rotation-gesture/rotation-gesture-recognizer.cpp
dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp
dali/internal/event/events/tap-gesture/tap-gesture-processor.h
dali/internal/event/events/tap-gesture/tap-gesture-recognizer.cpp
dali/internal/event/events/touch-event-impl.h
dali/public-api/events/gesture-detector.cpp
dali/public-api/events/gesture-detector.h

index 3ed67dd..54d5556 100644 (file)
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/events/long-press-gesture-detector-devel.h>
 #include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
 #include <dali/integration-api/input-options.h>
 #include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/public-api/dali-core.h>
 #include <stdlib.h>
 #include <test-touch-event-utils.h>
@@ -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;
+}
index a1d4483..3206272 100644 (file)
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/events/pan-gesture-devel.h>
 #include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
 #include <dali/integration-api/input-options.h>
 #include <dali/integration-api/profiling.h>
 #include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/public-api/dali-core.h>
 #include <stdlib.h>
 #include <test-touch-event-utils.h>
@@ -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;
+}
index 2c45979..2937a40 100644 (file)
 #include <dali-test-suite-utils.h>
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
 #include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/public-api/dali-core.h>
 #include <stdlib.h>
 #include <test-touch-event-utils.h>
@@ -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;
+}
index 8c1d929..6b5b333 100644 (file)
 #include <dali-test-suite-utils.h>
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
 #include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/public-api/dali-core.h>
 #include <stdlib.h>
 #include <test-touch-event-utils.h>
@@ -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;
+}
index 5c15b92..09f176f 100644 (file)
 #include <dali-test-suite-utils.h>
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
 #include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/public-api/dali-core.h>
 #include <stdlib.h>
 #include <test-touch-event-utils.h>
@@ -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;
+}
index b3b8981..dfa343f 100644 (file)
@@ -27,6 +27,8 @@
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/events/actor-gesture-data.h>
 #include <dali/internal/event/events/gesture-event-processor.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
 
 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()) ||
index dd312e6..1a4ecaa 100644 (file)
@@ -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.
    */
index 99dd285..a45500a 100644 (file)
@@ -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())
index 212b6bf..30d7836 100644 (file)
@@ -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.
index d803dcf..87b4cb4 100644 (file)
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali/integration-api/events/event.h>
 #include <dali/internal/event/events/gesture-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
 
 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.
index a2d581c..2a3c538 100644 (file)
@@ -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);
index e2015f3..4c8491b 100644 (file)
@@ -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.
index 0bc013d..498879e 100644 (file)
@@ -20,7 +20,9 @@
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/internal/event/events/actor-observer.h>
 #include <dali/internal/event/events/gesture-event.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/events/gesture.h>
 #include <dali/public-api/math/vector2.h>
@@ -42,7 +44,7 @@ template<typename T>
 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<GestureRecognizer>;
index 6b680ae..a2cc919 100644 (file)
@@ -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
index 0543748..b3d1437 100644 (file)
@@ -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.
index eac654b..93aad44 100644 (file)
@@ -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());
     }
   }
 }
index eaaff7a..3a471d3 100644 (file)
@@ -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
index bfeb623..4209c24 100644 (file)
@@ -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.
index 4e6ad9e..4e7af02 100644 (file)
@@ -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());
   }
 }
 
index 73e8dcd..7f25011 100644 (file)
@@ -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;
index 9d7acf0..e5f71d7 100644 (file)
@@ -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.
index 9ab75a2..49df4ae 100644 (file)
@@ -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());
   }
 }
 
index a83b1b2..111e7c1 100644 (file)
@@ -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;
index f1459bc..b1d1fa7 100644 (file)
@@ -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.
index dc10844..37aa79a 100644 (file)
@@ -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());
   }
 }
 
index bb4cfa7..0f1418a 100644 (file)
@@ -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;
     }
index 6b1ab28..b5f8a27 100644 (file)
@@ -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.
index cfa5d72..b59ccb2 100644 (file)
@@ -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());
   }
 }
 
index e59c597..e645c75 100644 (file)
@@ -183,6 +183,11 @@ public:
     return mRenderTask;
   }
 
+  Dali::RenderTask& GetRenderTaskPtr()
+  {
+    return mRenderTask;
+  }
+
   // Setters
 
   /**
index d1d6d0e..a9cc55a 100644 (file)
@@ -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
index 432d9bc..e94959d 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/object/handle.h>
+#include <dali/public-api/events/touch-event.h>
 
 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
   /**