Add Gesture Propagation
authorJoogab Yun <joogab.yun@samsung.com>
Tue, 11 May 2021 07:13:35 +0000 (16:13 +0900)
committerTaehyub Kim <taehyub.kim@samsung.com>
Tue, 8 Jun 2021 03:23:00 +0000 (12:23 +0900)
This is used when the parent actor wants to listen to gesture events.

example)
  The child is overlapped on the parent.
  So, if you tap a child, the parent cannot listen to the tap event.
  Now, If set to SetNeedGesturePropagation(true), the parent can receive gesture events.

 {
     Actor parent = Actor::New();
     Actor child = Actor::New();
     parent.Add(child);
     pTapDetector = TapGestureDetector::New();
     cTapDetector = TapGestureDetector::New();
     pTapDetector.Attach(parent);
     cTapDetector.Attach(child);
     pTapDetector.DetectedSignal().Connect(this, &OnParentTap);
     cTapDetector.DetectedSignal().Connect(this, &OnChildTap);
  }

  void OnChildTap(Dali::Actor actor, const Dali::TapGesture& tap)
  {
     // If you set SetNeedGesturePropagation to true here, the parent actor can also listen to events
     Dali::DevelActor::SetNeedGesturePropagation(Self(), true);
  }

Change-Id: I0e6c16c2b2dec1dfa873caa453302cc746c3f258

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/devel-api/actors/actor-devel.cpp
dali/devel-api/actors/actor-devel.h [changed mode: 0755->0644]
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/events/gesture-processor.cpp

index e179f2d..983aefe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -16,6 +16,7 @@
  */
 
 #include <dali-test-suite-utils.h>
+#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/input-options.h>
@@ -1081,3 +1082,59 @@ int UtcDaliLongPressGestureDisableDetectionDuringLongPressN(void)
 
   END_TEST;
 }
+
+int UtcDaliLongPressGestureWhenGesturePropargation(void)
+{
+  TestApplication application;
+
+  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.Attach(parentActor);
+  parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+  SignalData             cData;
+  GestureReceivedFunctor cFunctor(cData);
+
+  LongPressGestureDetector childDetector = LongPressGestureDetector::New();
+  childDetector.Attach(childActor);
+  childDetector.DetectedSignal().Connect(&application, cFunctor);
+
+  // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
+  TestGenerateLongPress(application, 50.0f, 50.0f);
+  TestEndLongPress(application, 50.0f, 50.0f);
+
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  // If GesturePropargation is set, a gesture event is to pass over to the parent.
+  Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
+
+  // So now the parent got the gesture event.
+  TestGenerateLongPress(application, 50.0f, 50.0f);
+  TestEndLongPress(application, 50.0f, 50.0f);
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  END_TEST;
+}
index 180c1c3..98019b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -16,6 +16,7 @@
  */
 
 #include <dali-test-suite-utils.h>
+#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/input-options.h>
@@ -2924,3 +2925,88 @@ int UtcDaliPanGestureDisableDetectionDuringPanN(void)
 
   END_TEST;
 }
+
+int UtcDaliPanGestureWhenGesturePropargation(void)
+{
+  TestApplication application;
+
+  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.Attach(parentActor);
+  parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+  SignalData             cData;
+  GestureReceivedFunctor cFunctor(cData);
+
+  PanGestureDetector childDetector = PanGestureDetector::New();
+  childDetector.Attach(childActor);
+  childDetector.DetectedSignal().Connect(&application, cFunctor);
+
+  // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
+  uint32_t time = 100;
+  TestStartPan(application, Vector2(10.0f, 20.0f), Vector2(26.0f, 20.0f), time);
+
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  TestMovePan(application, Vector2(26.0f, 4.0f), time);
+  time += TestGetFrameInterval();
+
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  TestEndPan(application, Vector2(26.0f, 20.0f), time);
+
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  // If GesturePropargation is set, a gesture event is to pass over to the parent.
+  Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
+
+  // So now the parent got the gesture event.
+  TestStartPan(application, Vector2(10.0f, 20.0f), Vector2(26.0f, 20.0f), time);
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  TestMovePan(application, Vector2(26.0f, 4.0f), time);
+  time += TestGetFrameInterval();
+
+  // child does not receive gestures. This is because we have passed the permission of the gesture to the parent.
+  DALI_TEST_EQUALS(false, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  TestEndPan(application, Vector2(26.0f, 20.0f), time);
+  DALI_TEST_EQUALS(false, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  END_TEST;
+}
index a25a0e6..e746f73 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -16,6 +16,7 @@
  */
 
 #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/render-task-list-integ.h>
 #include <dali/public-api/dali-core.h>
@@ -1148,3 +1149,81 @@ int UtcDaliPinchGestureDisableDetectionDuringPinchN(void)
 
   END_TEST;
 }
+
+int UtcDaliPinchGestureWhenGesturePropargation(void)
+{
+  TestApplication application;
+
+  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.Attach(parentActor);
+  parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+  SignalData             cData;
+  GestureReceivedFunctor cFunctor(cData);
+
+  PinchGestureDetector childDetector = PinchGestureDetector::New();
+  childDetector.Attach(childActor);
+  childDetector.DetectedSignal().Connect(&application, cFunctor);
+
+  // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
+  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, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  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, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  TestEndPinch(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 300);
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  // If GesturePropargation is set, a gesture event is to pass over to the parent.
+  Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
+
+  // So now the parent got the gesture event.
+  TestStartPinch(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 700);
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  // child does not receive gestures. This is because we have passed the permission of the gesture to the parent.
+  TestContinuePinch(application, Vector2(112.0f, 100.0f), Vector2(112.0f, 124.0f), Vector2(5.0f, 5.0f), Vector2(35.0f, 35.0f), 800);
+  DALI_TEST_EQUALS(false, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  TestEndPinch(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 900);
+  DALI_TEST_EQUALS(false, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  END_TEST;
+}
\ No newline at end of file
index 2f3e3f9..2fa5aec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -16,6 +16,7 @@
  */
 
 #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/render-task-list-integ.h>
 #include <dali/public-api/dali-core.h>
@@ -1136,3 +1137,58 @@ int UtcDaliRotationGestureDisableDetectionDuringRotationN(void)
 
   END_TEST;
 }
+
+int UtcDaliRotationGestureWhenGesturePropargation(void)
+{
+  TestApplication application;
+
+  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.Attach(parentActor);
+  parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+  SignalData             cData;
+  GestureReceivedFunctor cFunctor(cData);
+
+  RotationGestureDetector childDetector = RotationGestureDetector::New();
+  childDetector.Attach(childActor);
+  childDetector.DetectedSignal().Connect(&application, cFunctor);
+
+  // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
+  TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
+  TestEndRotation(application, Vector2(6.0f, 6.0f), Vector2(18.0f, 18.0f), Vector2(10.0f, 8.0f), Vector2(14.0f, 16.0f), 300);
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  // If GesturePropargation is set, a gesture event is to pass over to the parent.
+  Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
+
+  // So now the parent got the gesture event.
+  TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 700);
+  TestEndRotation(application, Vector2(6.0f, 6.0f), Vector2(18.0f, 18.0f), Vector2(10.0f, 8.0f), Vector2(14.0f, 16.0f), 900);
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  END_TEST;
+}
\ No newline at end of file
index 9204c5f..9cc4caf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -16,6 +16,7 @@
  */
 
 #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/render-task-list-integ.h>
 #include <dali/public-api/dali-core.h>
@@ -990,3 +991,56 @@ int UtcDaliTapGestureDisableDetectionDuringTapN(void)
 
   END_TEST;
 }
+
+int UtcDaliTapGestureWhenGesturePropargation(void)
+{
+  TestApplication application;
+
+  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.Attach(parentActor);
+  parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+  SignalData             cData;
+  GestureReceivedFunctor cFunctor(cData);
+
+  TapGestureDetector childDetector = TapGestureDetector::New();
+  childDetector.Attach(childActor);
+  childDetector.DetectedSignal().Connect(&application, cFunctor);
+
+  // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
+  TestGenerateTap(application, 50.0f, 50.0f, 100);
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  // If GesturePropargation is set, a gesture event is delivered to the parent.
+  Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
+
+  // So now the parent got the gesture event.
+  TestGenerateTap(application, 50.0f, 50.0f, 700);
+  DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+  cData.Reset();
+  pData.Reset();
+
+  END_TEST;
+}
index fd08434..9923967 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -53,6 +53,11 @@ Actor::TouchEventSignalType& InterceptTouchedSignal(Actor actor)
   return GetImplementation(actor).InterceptTouchedSignal();
 }
 
+void SetNeedGesturePropagation(Actor actor, bool propagation)
+{
+  return GetImplementation(actor).SetNeedGesturePropagation(propagation);
+}
+
 } // namespace DevelActor
 
 } // namespace Dali
old mode 100755 (executable)
new mode 100644 (file)
index c340ccd..f46478e
@@ -291,6 +291,35 @@ DALI_CORE_API ChildOrderChangedSignalType& ChildOrderChangedSignal(Actor actor);
  */
 DALI_CORE_API Actor::TouchEventSignalType& InterceptTouchedSignal(Actor actor);
 
+/**
+ * @brief This is used when the parent actor wants to listen to gesture events.
+ *
+ * @note example The child is overlapped on the parent.
+ * Currently, if you tap a child, the parent cannot listen to the tap event.
+ * Now, If set to SetNeedGesturePropagation(true), the parent can receive gesture events.
+ * Please call this setting inside a gesture callback, it will be reset after the gesture callback is called.
+ * @code
+ * {
+ *    Actor parent = Actor::New();
+ *    Actor child = Actor::New();
+ *    parent.Add(child);
+ *    parentTapDetector = TapGestureDetector::New();
+ *    childTapDetector = TapGestureDetector::New();
+ *    parentTapDetector.Attach(parent);
+ *    childTapDetector.Attach(child);
+ *    parentTapDetector.DetectedSignal().Connect(this, &OnParentTap);
+ *    childTapDetector.DetectedSignal().Connect(this, &OnChildTap);
+ * }
+ * void OnChildTap(Dali::Actor actor, const Dali::TapGesture& tap)
+ * {
+ *    // If you set SetNeedGesturePropagation to true here, the parent actor can also listen to events
+ *    Dali::DevelActor::SetNeedGesturePropagation(Self(), true);
+ * }
+ * @endcode
+ *
+ */
+DALI_CORE_API void SetNeedGesturePropagation(Actor actor, bool propagation);
+
 } // namespace DevelActor
 
 } // namespace Dali
index 776c3f3..c06b2a4 100644 (file)
@@ -1341,12 +1341,13 @@ Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
   mVisible(true),
   mInheritLayoutDirection(true),
   mCaptureAllTouchAfterStart(false),
+  mIsBlendEquationSet(false),
+  mNeedGesturePropagation(false),
   mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
   mDrawMode(DrawMode::NORMAL),
   mColorMode(Node::DEFAULT_COLOR_MODE),
   mClippingMode(ClippingMode::DISABLED),
-  mBlendEquation(DevelBlendEquation::ADD),
-  mIsBlendEquationSet(false)
+  mBlendEquation(DevelBlendEquation::ADD)
 {
 }
 
@@ -1878,6 +1879,16 @@ Rect<> Actor::CalculateScreenExtents() const
   return {position.x, position.y, size.x, size.y};
 }
 
+void Actor::SetNeedGesturePropagation(bool propagation)
+{
+  mNeedGesturePropagation = propagation;
+}
+
+bool Actor::NeedGesturePropagation()
+{
+  return mNeedGesturePropagation;
+}
+
 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
 {
   return PropertyHandler::GetCachedPropertyValue(*this, index, value);
index eb0ee82..2857f87 100644 (file)
@@ -254,6 +254,17 @@ public:
   Rect<> CalculateScreenExtents() const;
 
   /**
+   * @copydoc DevelActor::SetNeedGesturePropagation.
+   */
+  void SetNeedGesturePropagation(bool propagation);
+
+  /**
+   * Retrieve need gesture propagation value
+   * @return The actor's need gesture propagation value.
+   */
+  bool NeedGesturePropagation();
+
+  /**
    * Sets the size of an actor.
    * This does not interfere with the actors scale factor.
    * @param [in] width  The new width.
@@ -2046,12 +2057,13 @@ protected:
   bool                     mVisible : 1;                   ///< Cached: Whether the actor is visible or not.
   bool                     mInheritLayoutDirection : 1;    ///< Whether the actor inherits the layout direction from parent.
   bool                     mCaptureAllTouchAfterStart : 1; ///< Whether the actor should capture all touch after touch starts even if the motion moves outside of the actor area.
+  bool                     mIsBlendEquationSet : 1;        ///< Flag to identify whether the Blend equation is set
+  bool                     mNeedGesturePropagation : 1;    ///< Whether the parent listens for gesture events or not
   LayoutDirection::Type    mLayoutDirection : 2;           ///< Layout direction, Left to Right or Right to Left.
   DrawMode::Type           mDrawMode : 3;                  ///< Cached: How the actor and its children should be drawn
   ColorMode                mColorMode : 3;                 ///< Cached: Determines whether mWorldColor is inherited
   ClippingMode::Type       mClippingMode : 3;              ///< Cached: Determines which clipping mode (if any) to use.
   DevelBlendEquation::Type mBlendEquation : 16;            ///< Cached: Determines which blend equation will be used to render renderers.
-  bool                     mIsBlendEquationSet : 1;        ///< Flag to identify whether the Blend equation is set
 
 private:
   static ActorContainer mNullChildren; ///< Empty container (shared by all actors, returned by GetChildren() const)
index 53bc5e4..551acc1 100644 (file)
@@ -143,7 +143,12 @@ void GestureProcessor::ProcessAndEmit(HitTestAlgorithm::Results& hitTestResults)
         {
           // Our gesture detector's attached actor WAS the hit actor so we can can emit the signal.
           EmitGestureSignal(actor, gestureDetectors, hitTestResults.actorCoordinates);
-          break; // We have found AND emitted a signal on the gestured actor, break out.
+          // If NeedGesturePropagation is true, it passes the gesture to the parent.
+          if(!actor->NeedGesturePropagation())
+          {
+            break; // We have found AND emitted a signal on the gestured actor, break out.
+          }
+          actor->SetNeedGesturePropagation(false);
         }
         else
         {
@@ -162,7 +167,12 @@ void GestureProcessor::ProcessAndEmit(HitTestAlgorithm::Results& hitTestResults)
                 {
                   // One of the parents was the gestured actor so we can emit the signal for that actor.
                   EmitGestureSignal(actor, gestureDetectors, hitPointLocal);
-                  break; // We have found AND emitted a signal on the gestured actor, break out.
+                  // If NeedGesturePropagation is true, it passes the gesture to the parent.
+                  if(!actor->NeedGesturePropagation())
+                  {
+                    break; // We have found AND emitted a signal on the gestured actor, break out.
+                  }
+                  actor->SetNeedGesturePropagation(false);
                 }
               }
             }