Revert "Revert "Revert "[Tizen] Revert "Use touch consumed return to set whether...
authorseungho <seungho@seungho.tn.corp.samsungelectronics.net>
Wed, 28 Oct 2020 12:21:58 +0000 (21:21 +0900)
committerseungho <seungho@seungho.tn.corp.samsungelectronics.net>
Wed, 28 Oct 2020 12:21:58 +0000 (21:21 +0900)
This reverts commit ac791d290a2050dc0166f6ad5bfe4158f889c60d.

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/event-processor.cpp
dali/internal/event/events/pinch-gesture/pinch-gesture-recognizer.cpp
dali/internal/event/events/rotation-gesture/rotation-gesture-recognizer.cpp
dali/internal/event/events/touch-event-processor.cpp
dali/internal/event/events/touch-event-processor.h
dali/public-api/actors/actor.h

index 1efae5d..e179f2d 100644 (file)
@@ -992,3 +992,92 @@ int UtcDaliLongPressGestureSetMinimumHoldingTime(void)
 
   END_TEST;
 }
+
+int UtcDaliLongPressGestureInterruptedWhenTouchConsumed(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  bool                           consume = false;
+  TouchEventFunctorConsumeSetter touchFunctor(consume);
+  actor.TouchedSignal().Connect(&application, touchFunctor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  // Start gesture within the actor's area, we should receive the gesture as the touch is NOT being consumed
+  TestGenerateLongPress(application, 50.0f, 50.0f);
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+  TestEndLongPress(application, 50.0f, 50.0f);
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  // Another gesture in the same location, this time we will not receive it as touch is being consumed
+  consume = true;
+  TestGenerateLongPress(application, 50.0f, 50.0f);
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+  TestEndLongPress(application, 50.0f, 50.0f);
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLongPressGestureDisableDetectionDuringLongPressN(void)
+{
+  // Crash occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
+
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Add a detector
+  LongPressGestureDetector detector      = LongPressGestureDetector::New();
+  bool                     functorCalled = false;
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(
+    &application,
+    [&detector, &functorCalled](Actor actor, const LongPressGesture& gesture) {
+      if(gesture.GetState() == GestureState::FINISHED)
+      {
+        detector.Detach(actor);
+        functorCalled = true;
+      }
+    });
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Try the gesture, should not crash
+  try
+  {
+    TestGenerateLongPress(application, 50.0f, 10.0f);
+    TestEndLongPress(application, 50.0f, 10.0f);
+
+    DALI_TEST_CHECK(true); // No crash, test has passed
+    DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false); // If we crash, the test has failed
+  }
+
+  END_TEST;
+}
index 2cfadee..180c1c3 100644 (file)
@@ -2833,3 +2833,94 @@ int UtcDaliPanGestureNoTimeDiff(void)
 
   END_TEST;
 }
+
+int UtcDaliPanGestureInterruptedWhenTouchConsumed(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  bool                           consume = false;
+  TouchEventFunctorConsumeSetter touchFunctor(consume);
+  actor.TouchedSignal().Connect(&application, touchFunctor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+
+  PanGestureDetector detector = PanGestureDetector::New();
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  // Start gesture within the actor's area, we should receive the pan as the touch is NOT being consumed
+  uint32_t time = 100;
+  TestStartPan(application, Vector2(10.0f, 20.0f), Vector2(26.0f, 20.0f), time);
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
+  data.Reset();
+
+  // Continue the gesture within the actor's area, but now the touch consumes thus cancelling the gesture
+  consume = true;
+
+  TestMovePan(application, Vector2(26.0f, 4.0f), time);
+  time += TestGetFrameInterval();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(GestureState::CANCELLED, data.receivedGesture.GetState(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureDisableDetectionDuringPanN(void)
+{
+  // Crash occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
+
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Add a pan detector
+  PanGestureDetector detector      = PanGestureDetector::New();
+  bool               functorCalled = false;
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(
+    &application,
+    [&detector, &functorCalled](Actor actor, const PanGesture& pan) {
+      if(pan.GetState() == GestureState::FINISHED)
+      {
+        detector.Detach(actor);
+        functorCalled = true;
+      }
+    });
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Try the gesture, should not crash
+  try
+  {
+    uint32_t time = 100;
+    TestStartPan(application, Vector2(10.0f, 20.0f), Vector2(26.0f, 20.0f), time);
+    TestEndPan(application, Vector2(26.0f, 20.0f));
+
+    DALI_TEST_CHECK(true); // No crash, test has passed
+    DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false); // If we crash, the test has failed
+  }
+
+  END_TEST;
+}
index 84b6c67..a25a0e6 100644 (file)
@@ -1054,3 +1054,97 @@ int UtcDaliPinchGestureLayerConsumesTouch(void)
 
   END_TEST;
 }
+
+int UtcDaliPinchGestureInterruptedWhenTouchConsumed(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  bool                           consume = false;
+  TouchEventFunctorConsumeSetter touchFunctor(consume);
+  actor.TouchedSignal().Connect(&application, touchFunctor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  // Start gesture within the actor's area, we should receive the pinch as the touch is NOT being consumed
+  TestStartPinch(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
+  data.Reset();
+
+  // Continue the gesture within the actor's area, but now the touch consumes thus cancelling the gesture
+  consume = true;
+
+  TestContinuePinch(application, Vector2(112.0f, 100.0f), Vector2(112.0f, 124.0f), Vector2(5.0f, 5.0f), Vector2(35.0f, 35.0f), 200);
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(GestureState::CANCELLED, data.receivedGesture.GetState(), TEST_LOCATION);
+  data.Reset();
+
+  // Start another pinch, we should not even get the callback this time
+  TestStartPinch(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureDisableDetectionDuringPinchN(void)
+{
+  // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
+
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Add a detector
+  PinchGestureDetector detector      = PinchGestureDetector::New();
+  bool                 functorCalled = false;
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(
+    &application,
+    [&detector, &functorCalled](Actor actor, const PinchGesture& gesture) {
+      if(gesture.GetState() == GestureState::FINISHED)
+      {
+        detector.Detach(actor);
+        functorCalled = true;
+      }
+    });
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Try the gesture, should not crash
+  try
+  {
+    TestStartPinch(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
+    TestContinuePinch(application, Vector2(112.0f, 100.0f), Vector2(112.0f, 124.0f), Vector2(5.0f, 5.0f), Vector2(35.0f, 35.0f), 200);
+    TestEndPinch(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
+
+    DALI_TEST_CHECK(true); // No crash, test has passed
+    DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false); // If we crash, the test has failed
+  }
+
+  END_TEST;
+}
index f91fe73..2f3e3f9 100644 (file)
@@ -1044,3 +1044,95 @@ int UtcDaliRotationGestureLayerConsumesTouch(void)
   END_TEST;
 }
 
+int UtcDaliRotationGestureInterruptedWhenTouchConsumed(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  bool                           consume = false;
+  TouchEventFunctorConsumeSetter touchFunctor(consume);
+  actor.TouchedSignal().Connect(&application, touchFunctor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+
+  RotationGestureDetector detector = RotationGestureDetector::New();
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  // Start gesture within the actor's area, we should receive the rotation as the touch is NOT being consumed
+  TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
+  data.Reset();
+
+  // Continue the gesture within the actor's area, but now the touch consumes thus cancelling the gesture
+  consume = true;
+
+  TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(GestureState::CANCELLED, data.receivedGesture.GetState(), TEST_LOCATION);
+  data.Reset();
+
+  // Start another rotation, we should not even get the callback this time
+  TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliRotationGestureDisableDetectionDuringRotationN(void)
+{
+  // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
+
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Add a detector
+  RotationGestureDetector detector      = RotationGestureDetector::New();
+  bool                    functorCalled = false;
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(
+    &application,
+    [&detector, &functorCalled](Actor actor, const RotationGesture& gesture) {
+      if(gesture.GetState() == GestureState::FINISHED)
+      {
+        detector.Detach(actor);
+        functorCalled = true;
+      }
+    });
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Try the gesture, should not crash
+  try
+  {
+    TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
+    TestContinueRotation(application, Vector2(112.0f, 100.0f), Vector2(112.0f, 124.0f), Vector2(5.0f, 5.0f), Vector2(35.0f, 35.0f), 200);
+    TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
+
+    DALI_TEST_CHECK(true); // No crash, test has passed
+    DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false); // If we crash, the test has failed
+  }
+
+  END_TEST;
+}
index 23e6d77..9204c5f 100644 (file)
@@ -910,3 +910,83 @@ int UtcDaliTapGestureLayerConsumesTouch(void)
 
   END_TEST;
 }
+
+int UtcDaliTapGestureInterruptedWhenTouchConsumed(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  bool                           consume = false;
+  TouchEventFunctorConsumeSetter touchFunctor(consume);
+  actor.TouchedSignal().Connect(&application, touchFunctor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+
+  TapGestureDetector detector = TapGestureDetector::New();
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  // Start gesture within the actor's area, we should receive the gesture as the touch is NOT being consumed
+  TestGenerateTap(application, 50.0f, 50.0f);
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  // Another gesture in the same location, this time we will not receive it as touch is being consumed
+  consume = true;
+  TestGenerateTap(application, 50.0f, 50.0f);
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliTapGestureDisableDetectionDuringTapN(void)
+{
+  // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
+
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Add a detector
+  TapGestureDetector detector      = TapGestureDetector::New();
+  bool               functorCalled = false;
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(
+    &application,
+    [&detector, &functorCalled](Actor actor, const TapGesture& gesture) {
+      detector.Detach(actor);
+      functorCalled = true;
+    });
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Try the gesture, should not crash
+  try
+  {
+    TestGenerateTap(application, 50.0f, 10.0f);
+
+    DALI_TEST_CHECK(true); // No crash, test has passed
+    DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false); // If we crash, the test has failed
+  }
+
+  END_TEST;
+}
index c22d5f5..ff6007b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -152,8 +152,18 @@ void EventProcessor::ProcessEvents()
     {
       case Event::Touch:
       {
-        mTouchEventProcessor.ProcessTouchEvent( static_cast<const Integration::TouchEvent&>(*event) );
-        mGestureEventProcessor.ProcessTouchEvent(mScene, static_cast<const Integration::TouchEvent&>(*event));
+        Integration::TouchEvent& touchEvent = static_cast<Integration::TouchEvent&>(*event);
+        const bool consumed = mTouchEventProcessor.ProcessTouchEvent( touchEvent );
+
+        // If touch is consumed, then gestures should be cancelled
+        // Do this by sending an interrupted event to the GestureEventProcessor
+        if( consumed )
+        {
+          Integration::Point& point = touchEvent.GetPoint(0);
+          point.SetState( PointState::INTERRUPTED );
+        }
+
+        mGestureEventProcessor.ProcessTouchEvent(mScene, touchEvent);
         break;
       }
 
index 5381c2b..134dee4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -118,7 +118,7 @@ void PinchGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
         const Integration::Point& currentPoint1 = event.points[0];
         const Integration::Point& currentPoint2 = event.points[1];
 
-        if (currentPoint1.GetState() == PointState::UP || currentPoint2.GetState() == PointState::UP)
+        if (currentPoint1.GetState() == PointState::UP || currentPoint2.GetState() == PointState::UP || currentPoint1.GetState() == PointState::INTERRUPTED)
         {
           // One of our touch points has an Up event so change our state back to CLEAR.
           mState = CLEAR;
index 49d84b3..6f85907 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -96,7 +96,7 @@ void RotationGestureRecognizer::SendEvent( const Integration::TouchEvent& event
         const Integration::Point& currentPoint1 = event.points[0];
         const Integration::Point& currentPoint2 = event.points[1];
 
-        if( currentPoint1.GetState() == PointState::UP || currentPoint2.GetState() == PointState::UP )
+        if( currentPoint1.GetState() == PointState::UP || currentPoint2.GetState() == PointState::UP || currentPoint1.GetState() == PointState::INTERRUPTED )
         {
           // One of our touch points has an Up event so change our state back to CLEAR.
           mState = CLEAR;
index b902e84..864ce8c 100644 (file)
@@ -202,7 +202,7 @@ TouchEventProcessor::~TouchEventProcessor()
   DALI_LOG_TRACE_METHOD( gLogFilter );
 }
 
-void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& event )
+bool TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& event )
 {
   DALI_LOG_TRACE_METHOD( gLogFilter );
   DALI_ASSERT_ALWAYS( !event.points.empty() && "Empty TouchEvent sent from Integration\n" );
@@ -264,7 +264,7 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
     touchEventImpl->AddPoint( currentPoint );
 
     mScene.EmitTouchedSignal( touchEventHandle );
-    return; // No need for hit testing
+    return false; // No need for hit testing & already an interrupted event so just return false
   }
 
   // 2) Hit Testing.
@@ -309,11 +309,14 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
 
   // 3) Recursively deliver events to the actor and its parents, until the event is consumed or the stage is reached.
 
+  bool consumed = false;
+
   // Emit the touch signal
   Dali::Actor consumedActor;
   if ( currentRenderTask )
   {
     consumedActor = EmitTouchSignals( touchEventImpl->GetPoint( 0 ).GetHitActor(), touchEventHandle );
+    consumed = consumedActor ? true : false;
   }
 
   Integration::Point& primaryPoint = touchEventImpl->GetPoint( 0 );
@@ -363,6 +366,8 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
         }
       }
 
+      consumed |= leaveEventConsumer ? true : false;
+
       // Check if the motion event has been consumed by another actor's listener.  In this case, the previously
       // consumed actor's listeners may need to be informed (through a leave event).
       // Further checks here to ensure we do not signal the same actor twice for the same event.
@@ -474,6 +479,8 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
       }
     }
   }
+
+  return consumed;
 }
 
 void TouchEventProcessor::OnObservedActorDisconnected( Actor* actor )
index 9306e6f..c2e4bc7 100644 (file)
@@ -67,8 +67,9 @@ public:
   /**
    * This function is called by the event processor whenever a touch event occurs.
    * @param[in] event The touch event that has occurred.
+   * @return true if consumed
    */
-  void ProcessTouchEvent( const Integration::TouchEvent& event );
+  bool ProcessTouchEvent( const Integration::TouchEvent& event );
 
 private:
 
index 42c772d..71fa8c7 100644 (file)
@@ -215,10 +215,6 @@ using Padding = Rect<float>; ///< Padding definition @SINCE_1_0.0
  *   - If the consumed actor on hover-start is not the same as the consumed actor on hover-finished, then
  *     hover signals are also emitted from the hover-started actor with an "Interrupted" state.
  *
- * <h3>Key Events:</h3>
- *
- * Key events are received by an actor once set to grab key events, only one actor can be set as focused.
- *
  * @nosubgrouping
  *
  * Signals
@@ -1170,7 +1166,8 @@ public: // Signals
    * @endcode
    * The return value of True, indicates that the touch event has been consumed.
    * Otherwise the signal will be emitted on the next sensitive parent of the actor.
-   * @SINCE_1_1.37
+   * A true return will also cancel any ongoing gestures.
+   * @SINCE_1_9.28
    * @return The signal to connect to
    * @pre The Actor has been initialized.
    */