(HitTest) Added API to layer so that it can consume all touch if required 82/24082/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 18 Jun 2014 01:17:26 +0000 (10:17 +0900)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 8 Jul 2014 13:15:32 +0000 (14:15 +0100)
[problem]     Currently, the only way to stop gestures being delivered to actors behind a layer is
              by attaching the layer to a gesture detector which is cumbersome.
[cause]       N/A
[solution]    Implemented an API which allows the user to set whether a layer should consume all
              touch. When this is set on a layer, any layers behind that layer are not hit-test.

Change-Id: I34468c13a3b7b5f81a53ca4746a5c97a4ece09ba
Signed-off-by: Adeel Kazmi <adeel.kazmi@samsung.com>
15 files changed:
automated-tests/src/dali/tct-dali-core.h
automated-tests/src/dali/utc-Dali-Layer.cpp
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-TapGestureDetector.cpp
automated-tests/src/dali/utc-Dali-TouchProcessing.cpp
capi/dali/public-api/actors/actor.h
capi/dali/public-api/actors/layer.h
dali/internal/event/actors/layer-impl.cpp
dali/internal/event/actors/layer-impl.h
dali/internal/event/events/gesture-processor.cpp
dali/internal/event/events/hit-test-algorithm-impl.cpp
dali/internal/event/events/hit-test-algorithm-impl.h
dali/public-api/actors/layer.cpp

index 23066b4..106da49 100644 (file)
@@ -741,6 +741,7 @@ extern int UtcDaliLayerDefaultProperties(void);
 extern int UtcDaliLayerSetDepthTestDisabled(void);
 extern int UtcDaliLayerCreateDestroy(void);
 extern int UtcDaliLayerPropertyIndices(void);
+extern int UtcDaliLayerTouchConsumed(void);
 extern int UtcDaliLongPressGestureConstructor(void);
 extern int UtcDaliLongPressGestureAssignment(void);
 extern int UtcDaliLongPressGestureDetectorConstructor(void);
@@ -771,6 +772,7 @@ extern int UtcDaliLongPressGestureActorStagedAndDestroyed(void);
 extern int UtcDaliLongPressGestureSystemOverlay(void);
 extern int UtcDaliLongPressGestureBehindTouchableSystemOverlay(void);
 extern int UtcDaliLongPressGestureTouchBehindGesturedSystemOverlay(void);
+extern int UtcDaliLongPressGestureLayerConsumesTouch(void);
 extern int UtcDaliMaterialNew01(void);
 extern int UtcDaliMaterialDownCast(void);
 extern int UtcDaliMaterialSettersAndGetters(void);
@@ -877,6 +879,7 @@ extern int UtcDaliPanGestureDirectionProcessing(void);
 extern int UtcDaliPanGestureSetProperties(void);
 extern int UtcDaliPanGestureSetPropertiesAlreadyPanning(void);
 extern int UtcDaliPanGesturePropertyIndices(void);
+extern int UtcDaliPanGestureLayerConsumesTouch(void);
 extern int UtcDaliPinchGestureConstructor(void);
 extern int UtcDaliPinchGestureAssignment(void);
 extern int UtcDaliPinchGestureDetectorConstructor(void);
@@ -903,6 +906,7 @@ extern int UtcDaliPinchGestureActorStagedAndDestroyed(void);
 extern int UtcDaliPinchGestureSystemOverlay(void);
 extern int UtcDaliPinchGestureBehindTouchableSystemOverlay(void);
 extern int UtcDaliPinchGestureTouchBehindGesturedSystemOverlay(void);
+extern int UtcDaliPinchGestureLayerConsumesTouch(void);
 extern int UtcDaliPixelHasAlpha(void);
 extern int UtcDaliPixelGetBytesPerPixel(void);
 extern int UtcDaliPixelGetAlphaOffsetAndMask(void);
@@ -1173,6 +1177,7 @@ extern int UtcDaliTapGestureActorRemovedWhilePossible(void);
 extern int UtcDaliTapGestureSystemOverlay(void);
 extern int UtcDaliTapGestureBehindTouchableSystemOverlay(void);
 extern int UtcDaliTapGestureTouchBehindGesturedSystemOverlay(void);
+extern int UtcDaliTapGestureLayerConsumesTouch(void);
 extern int UtcDaliTextConstructor(void);
 extern int UtcDaliTextCopyConstructor(void);
 extern int UtcDaliTextAssignmentOperator(void);
@@ -1266,6 +1271,7 @@ extern int UtcDaliTouchActorRemovedInSignal(void);
 extern int UtcDaliTouchActorSignalNotConsumed(void);
 extern int UtcDaliTouchActorUnStaged(void);
 extern int UtcDaliTouchSystemOverlayActor(void);
+extern int UtcDaliTouchLayerConsumesTouch(void);
 extern int UtcDaliVector2Cons(void);
 extern int UtcDaliVector2FitInside(void);
 extern int UtcDaliVector2FitScaleToFill(void);
@@ -1958,6 +1964,7 @@ testcase tc_array[] = {
     {"UtcDaliLayerSetDepthTestDisabled", UtcDaliLayerSetDepthTestDisabled, layer_test_startup, layer_test_cleanup},
     {"UtcDaliLayerCreateDestroy", UtcDaliLayerCreateDestroy, layer_test_startup, layer_test_cleanup},
     {"UtcDaliLayerPropertyIndices", UtcDaliLayerPropertyIndices, layer_test_startup, layer_test_cleanup},
+    {"UtcDaliLayerTouchConsumed", UtcDaliLayerTouchConsumed, layer_test_startup, layer_test_cleanup},
     {"UtcDaliLongPressGestureConstructor", UtcDaliLongPressGestureConstructor, utc_dali_long_press_gesture_startup, utc_dali_long_press_gesture_cleanup},
     {"UtcDaliLongPressGestureAssignment", UtcDaliLongPressGestureAssignment, utc_dali_long_press_gesture_startup, utc_dali_long_press_gesture_cleanup},
     {"UtcDaliLongPressGestureDetectorConstructor", UtcDaliLongPressGestureDetectorConstructor, utc_dali_long_press_gesture_detector_startup, utc_dali_long_press_gesture_detector_cleanup},
@@ -1988,6 +1995,7 @@ testcase tc_array[] = {
     {"UtcDaliLongPressGestureSystemOverlay", UtcDaliLongPressGestureSystemOverlay, utc_dali_long_press_gesture_detector_startup, utc_dali_long_press_gesture_detector_cleanup},
     {"UtcDaliLongPressGestureBehindTouchableSystemOverlay", UtcDaliLongPressGestureBehindTouchableSystemOverlay, utc_dali_long_press_gesture_detector_startup, utc_dali_long_press_gesture_detector_cleanup},
     {"UtcDaliLongPressGestureTouchBehindGesturedSystemOverlay", UtcDaliLongPressGestureTouchBehindGesturedSystemOverlay, utc_dali_long_press_gesture_detector_startup, utc_dali_long_press_gesture_detector_cleanup},
+    {"UtcDaliLongPressGestureLayerConsumesTouch", UtcDaliLongPressGestureLayerConsumesTouch, utc_dali_long_press_gesture_detector_startup, utc_dali_long_press_gesture_detector_cleanup},
     {"UtcDaliMaterialNew01", UtcDaliMaterialNew01, utc_dali_material_startup, utc_dali_material_cleanup},
     {"UtcDaliMaterialDownCast", UtcDaliMaterialDownCast, utc_dali_material_startup, utc_dali_material_cleanup},
     {"UtcDaliMaterialSettersAndGetters", UtcDaliMaterialSettersAndGetters, utc_dali_material_startup, utc_dali_material_cleanup},
@@ -2094,6 +2102,7 @@ testcase tc_array[] = {
     {"UtcDaliPanGestureSetProperties", UtcDaliPanGestureSetProperties, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup},
     {"UtcDaliPanGestureSetPropertiesAlreadyPanning", UtcDaliPanGestureSetPropertiesAlreadyPanning, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup},
     {"UtcDaliPanGesturePropertyIndices", UtcDaliPanGesturePropertyIndices, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup},
+    {"UtcDaliPanGestureLayerConsumesTouch", UtcDaliPanGestureLayerConsumesTouch, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup},
     {"UtcDaliPinchGestureConstructor", UtcDaliPinchGestureConstructor, utc_dali_pinch_gesture_startup, utc_dali_pinch_gesture_cleanup},
     {"UtcDaliPinchGestureAssignment", UtcDaliPinchGestureAssignment, utc_dali_pinch_gesture_startup, utc_dali_pinch_gesture_cleanup},
     {"UtcDaliPinchGestureDetectorConstructor", UtcDaliPinchGestureDetectorConstructor, utc_dali_pinch_gesture_detector_startup, utc_dali_pinch_gesture_detector_cleanup},
@@ -2120,6 +2129,7 @@ testcase tc_array[] = {
     {"UtcDaliPinchGestureSystemOverlay", UtcDaliPinchGestureSystemOverlay, utc_dali_pinch_gesture_detector_startup, utc_dali_pinch_gesture_detector_cleanup},
     {"UtcDaliPinchGestureBehindTouchableSystemOverlay", UtcDaliPinchGestureBehindTouchableSystemOverlay, utc_dali_pinch_gesture_detector_startup, utc_dali_pinch_gesture_detector_cleanup},
     {"UtcDaliPinchGestureTouchBehindGesturedSystemOverlay", UtcDaliPinchGestureTouchBehindGesturedSystemOverlay, utc_dali_pinch_gesture_detector_startup, utc_dali_pinch_gesture_detector_cleanup},
+    {"UtcDaliPinchGestureLayerConsumesTouch", UtcDaliPinchGestureLayerConsumesTouch, utc_dali_pinch_gesture_detector_startup, utc_dali_pinch_gesture_detector_cleanup},
     {"UtcDaliPixelHasAlpha", UtcDaliPixelHasAlpha, utc_dali_pixel_startup, utc_dali_pixel_cleanup},
     {"UtcDaliPixelGetBytesPerPixel", UtcDaliPixelGetBytesPerPixel, utc_dali_pixel_startup, utc_dali_pixel_cleanup},
     {"UtcDaliPixelGetAlphaOffsetAndMask", UtcDaliPixelGetAlphaOffsetAndMask, utc_dali_pixel_startup, utc_dali_pixel_cleanup},
@@ -2390,6 +2400,7 @@ testcase tc_array[] = {
     {"UtcDaliTapGestureSystemOverlay", UtcDaliTapGestureSystemOverlay, utc_dali_tap_gesture_detector_startup, utc_dali_tap_gesture_detector_cleanup},
     {"UtcDaliTapGestureBehindTouchableSystemOverlay", UtcDaliTapGestureBehindTouchableSystemOverlay, utc_dali_tap_gesture_detector_startup, utc_dali_tap_gesture_detector_cleanup},
     {"UtcDaliTapGestureTouchBehindGesturedSystemOverlay", UtcDaliTapGestureTouchBehindGesturedSystemOverlay, utc_dali_tap_gesture_detector_startup, utc_dali_tap_gesture_detector_cleanup},
+    {"UtcDaliTapGestureLayerConsumesTouch", UtcDaliTapGestureLayerConsumesTouch, utc_dali_tap_gesture_detector_startup, utc_dali_tap_gesture_detector_cleanup},
     {"UtcDaliTextConstructor", UtcDaliTextConstructor, utc_dali_text_startup, utc_dali_text_cleanup},
     {"UtcDaliTextCopyConstructor", UtcDaliTextCopyConstructor, utc_dali_text_startup, utc_dali_text_cleanup},
     {"UtcDaliTextAssignmentOperator", UtcDaliTextAssignmentOperator, utc_dali_text_startup, utc_dali_text_cleanup},
@@ -2483,6 +2494,7 @@ testcase tc_array[] = {
     {"UtcDaliTouchActorSignalNotConsumed", UtcDaliTouchActorSignalNotConsumed, utc_dali_touch_processing_startup, utc_dali_touch_processing_cleanup},
     {"UtcDaliTouchActorUnStaged", UtcDaliTouchActorUnStaged, utc_dali_touch_processing_startup, utc_dali_touch_processing_cleanup},
     {"UtcDaliTouchSystemOverlayActor", UtcDaliTouchSystemOverlayActor, utc_dali_touch_processing_startup, utc_dali_touch_processing_cleanup},
+    {"UtcDaliTouchLayerConsumesTouch", UtcDaliTouchLayerConsumesTouch, utc_dali_touch_processing_startup, utc_dali_touch_processing_cleanup},
     {"UtcDaliVector2Cons", UtcDaliVector2Cons, utc_dali_vector2_startup, utc_dali_vector2_cleanup},
     {"UtcDaliVector2FitInside", UtcDaliVector2FitInside, utc_dali_vector2_startup, utc_dali_vector2_cleanup},
     {"UtcDaliVector2FitScaleToFill", UtcDaliVector2FitScaleToFill, utc_dali_vector2_startup, utc_dali_vector2_cleanup},
index 23e9ddd..8e9dc56 100644 (file)
@@ -512,3 +512,14 @@ int UtcDaliLayerPropertyIndices(void)
   DALI_TEST_EQUALS( indices.size(), layer.GetPropertyCount(), TEST_LOCATION );
   END_TEST;
 }
+
+int UtcDaliLayerTouchConsumed(void)
+{
+  TestApplication application;
+  Layer layer = Layer::New();
+
+  DALI_TEST_EQUALS( layer.IsTouchConsumed(), false, TEST_LOCATION );
+  layer.SetTouchConsumed( true );
+  DALI_TEST_EQUALS( layer.IsTouchConsumed(), true, TEST_LOCATION );
+  END_TEST;
+}
index 1b04d5f..433082b 100644 (file)
@@ -1374,3 +1374,56 @@ int UtcDaliLongPressGestureTouchBehindGesturedSystemOverlay(void)
 
   END_TEST;
 }
+
+int UtcDaliLongPressGestureLayerConsumesTouch(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(actor);
+
+  // Add a detector
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect( &application, functor );
+
+  // Add a layer to overlap the actor
+  Layer layer = Layer::New();
+  layer.SetSize(100.0f, 100.0f);
+  layer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add( layer );
+  layer.RaiseToTop();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Vector2 screenCoords( 50.0f, 50.0f );
+
+  // Emit signals, should receive
+  application.ProcessEvent( GenerateLongPress( Gesture::Possible, 1u, screenCoords ) );
+  application.ProcessEvent( GenerateLongPress( Gesture::Started, 1u, screenCoords ) );
+  application.ProcessEvent( GenerateLongPress( Gesture::Finished, 1u, screenCoords ) );
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  // Set layer to consume all touch
+  layer.SetTouchConsumed( true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit the same signals again, should not receive
+  application.ProcessEvent( GenerateLongPress( Gesture::Possible, 1u, screenCoords ) );
+  application.ProcessEvent( GenerateLongPress( Gesture::Started, 1u, screenCoords ) );
+  application.ProcessEvent( GenerateLongPress( Gesture::Finished, 1u, screenCoords ) );
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
index 3a588e1..63f1203 100644 (file)
@@ -2133,3 +2133,54 @@ int UtcDaliPanGesturePropertyIndices(void)
   DALI_TEST_EQUALS( indices.size(), detector.GetPropertyCount(), TEST_LOCATION );
   END_TEST;
 }
+
+int UtcDaliPanGestureLayerConsumesTouch(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(actor);
+
+  // Add a pan detector
+  PanGestureDetector detector = PanGestureDetector::New();
+  detector.Attach( actor );
+  SignalData data;
+  GestureReceivedFunctor functor( data );
+  detector.DetectedSignal().Connect( &application, functor );
+
+  // Add a layer to overlap the actor
+  Layer layer = Layer::New();
+  layer.SetSize(100.0f, 100.0f);
+  layer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add( layer );
+  layer.RaiseToTop();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit signals, should receive
+  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  // Set layer to consume all touch
+  layer.SetTouchConsumed( true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit the same signals again, should not receive
+  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
index 2b487a5..bd8c58b 100644 (file)
@@ -1299,3 +1299,56 @@ int UtcDaliPinchGestureTouchBehindGesturedSystemOverlay(void)
 
   END_TEST;
 }
+
+int UtcDaliPinchGestureLayerConsumesTouch(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(actor);
+
+  // Add a detector
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  PinchGestureDetector detector = PinchGestureDetector::New();
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect( &application, functor );
+
+  // Add a layer to overlap the actor
+  Layer layer = Layer::New();
+  layer.SetSize(100.0f, 100.0f);
+  layer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add( layer );
+  layer.RaiseToTop();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Vector2 screenCoords( 50.0f, 50.0f );
+  float scale ( 10.0f );
+  float speed ( 50.0f );
+
+  // Emit signals, should receive
+  application.ProcessEvent( GeneratePinch( Gesture::Started, scale, speed, screenCoords ) );
+  application.ProcessEvent( GeneratePinch( Gesture::Finished, scale, speed, screenCoords ) );
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  // Set layer to consume all touch
+  layer.SetTouchConsumed( true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit the same signals again, should not receive
+  application.ProcessEvent( GeneratePinch( Gesture::Started, scale, speed, screenCoords ) );
+  application.ProcessEvent( GeneratePinch( Gesture::Finished, scale, speed, screenCoords ) );
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
index 3e8293e..0e85555 100644 (file)
@@ -1282,3 +1282,54 @@ int UtcDaliTapGestureTouchBehindGesturedSystemOverlay(void)
 
   END_TEST;
 }
+
+int UtcDaliTapGestureLayerConsumesTouch(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(actor);
+
+  // Add a detector
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  TapGestureDetector detector = TapGestureDetector::New();
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect( &application, functor );
+
+  // Add a layer to overlap the actor
+  Layer layer = Layer::New();
+  layer.SetSize(100.0f, 100.0f);
+  layer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add( layer );
+  layer.RaiseToTop();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Vector2 screenCoords( 50.0f, 50.0f );
+
+  // Emit signals, should receive
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, screenCoords ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, screenCoords ) );
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  // Set layer to consume all touch
+  layer.SetTouchConsumed( true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit the same signals again, should not receive
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, screenCoords ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, screenCoords ) );
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
index cdbf448..0847158 100644 (file)
@@ -1192,3 +1192,54 @@ int UtcDaliTouchSystemOverlayActor(void)
   DALI_TEST_CHECK( systemActor == data.touchedActor );
   END_TEST;
 }
+
+int UtcDaliTouchLayerConsumesTouch(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchEventFunctor functor( data );
+  actor.TouchedSignal().Connect( &application, functor );
+
+  // Add a layer to overlap the actor
+  Layer layer = Layer::New();
+  layer.SetSize(100.0f, 100.0f);
+  layer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add( layer );
+  layer.RaiseToTop();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit a few touch signals
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Up, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Set layer to consume all touch
+  layer.SetTouchConsumed( true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit the same signals again, should not receive
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Up, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
index 220f5b9..dddd842 100644 (file)
@@ -99,6 +99,7 @@ typedef ActorContainer::const_iterator ActorConstIter; ///< Const iterator for D
  *   - Before we perform a hit test within a layer, we check if all the layer's parents are visible
  *     and sensitive.
  *   - If they are not, we skip hit testing the actors in that layer altogether.
+ *   - If a layer is set to consume all touch, then we do not check any layers behind this layer.
  *
  * - Actors
  *   - The final part of hit testing is performed by walking through the actor tree within a layer.
index 7cb6e1f..b0fbe09 100644 (file)
@@ -303,6 +303,22 @@ public:
   */
   void SetSortFunction( SortFunctionType function );
 
+  /**
+   * @brief This allows the user to specify whether this layer should consume touch (including gestures).
+   *
+   * If set, any layers behind this layer will not be hit-test.
+   *
+   * @param[in]  consume  Whether the layer should consume touch (including gestures).
+   */
+  void SetTouchConsumed( bool consume );
+
+  /**
+   * @brief Retrieves whether the layer consumes touch (including gestures).
+   *
+   * @return true if consuming touch, false otherwise.
+   */
+  bool IsTouchConsumed() const;
+
 public: // Not intended for application developers
 
   /**
index 1aed323..fbe8973 100644 (file)
@@ -111,7 +111,8 @@ Layer::Layer( Actor::DerivedType type )
   mClippingBox(0,0,0,0),
   mSortFunction(Dali::Layer::ZValue),
   mIsClipping(false),
-  mDepthTestDisabled(false)
+  mDepthTestDisabled(false),
+  mTouchConsumed(false)
 {
 }
 
@@ -270,6 +271,16 @@ void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
   }
 }
 
+void Layer::SetTouchConsumed( bool consume )
+{
+  mTouchConsumed = consume;
+}
+
+bool Layer::IsTouchConsumed() const
+{
+  return mTouchConsumed;
+}
+
 SceneGraph::Node* Layer::CreateNode() const
 {
   return SceneGraph::Layer::New();
index e48e296..affc8cd 100644 (file)
@@ -160,6 +160,16 @@ public:
   void SetSortFunction(Dali::Layer::SortFunctionType function);
 
   /**
+   * @copydoc Dali::Layer::SetTouchConsumed()
+   */
+  void SetTouchConsumed( bool consume );
+
+  /**
+   * @copydoc Dali::Layer::IsTouchConsumed()
+   */
+  bool IsTouchConsumed() const;
+
+  /**
    * Helper function to get the scene object.
    * This should only be called by Stage
    * @return the scene object for the layer.
@@ -263,6 +273,7 @@ private:
 
   bool mIsClipping:1;                           ///< True when clipping is enabled
   bool mDepthTestDisabled:1;                    ///< Whether depth test is disabled.
+  bool mTouchConsumed:1;                        ///< Whether we should consume touch (including gesture).
 
   static bool mFirstInstance;
   static DefaultPropertyLookup* mDefaultLayerPropertyLookup; ///< Default properties
index 297a4bd..95f798f 100644 (file)
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/actors/actor-impl.h>
+#include <dali/internal/event/actors/layer-impl.h>
 #include <dali/internal/event/events/hit-test-algorithm-impl.h>
 #include <dali/internal/event/events/actor-gesture-data.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
@@ -56,6 +57,11 @@ struct GestureHitTestCheck : public HitTestAlgorithm::HitTestInterface
            actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
   }
 
+  virtual bool DoesLayerConsumeHit( Layer* layer )
+  {
+    return layer->IsTouchConsumed();
+  }
+
   Gesture::Type mType;
 };
 
index 49df17c..22fe563 100644 (file)
@@ -92,6 +92,14 @@ struct HitTestFunctionWrapper : public HitTestInterface
     return mFunc( Dali::Actor( actor ), Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE );
   }
 
+  virtual bool DoesLayerConsumeHit( Layer* layer )
+  {
+    // Layer::IsTouchConsumed() focuses on touch only. Here we are a wrapper for the public-api
+    // where the caller may want to check for something completely different.
+    // TODO: Should provide a means to let caller decide. For now do not allow layers to consume
+    return false;
+  }
+
   Dali::HitTestAlgorithm::HitTestFunction mFunc;
 };
 
@@ -112,6 +120,11 @@ struct ActorTouchableCheck : public HitTestInterface
     return actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
            actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
   }
+
+  virtual bool DoesLayerConsumeHit( Layer* layer )
+  {
+    return layer->IsTouchConsumed();
+  }
 };
 
 /**
@@ -351,6 +364,7 @@ bool HitTestRenderTask( LayerList& layers,
         HitActor hit;
         bool stencilOnLayer = false;
         bool stencilHit = false;
+        bool layerConsumesHit = false;
         const Vector2& stageSize = Stage::GetCurrent()->GetSize();
 
         for (int i=layers.GetLayerCount()-1; i>=0 && !(hit.actor); --i)
@@ -375,11 +389,19 @@ bool HitTestRenderTask( LayerList& layers,
               // Recursively hit test all the actors, without crossing into other layers.
               hit = HitTestWithinLayer( *layer, results.rayOrigin, results.rayDirection, false, nearClippingPlane, farClippingPlane, hitCheck, stencilOnLayer, stencilHit, false );
             }
+
             // If a stencil on this layer hasn't been hit, then discard hit results for this layer
             if ( stencilOnLayer && !stencilHit )
             {
              hit = previousHit;
             }
+
+            // If this layer is set to consume the hit, then do not check any layers behind it
+            if ( hitCheck.DoesLayerConsumeHit( layer ) )
+            {
+              layerConsumesHit = true;
+              break;
+            }
           }
         }
         if ( hit.actor )
@@ -390,6 +412,10 @@ bool HitTestRenderTask( LayerList& layers,
           results.actorCoordinates.y = hit.y;
           return true; // Success
         }
+        else if ( layerConsumesHit )
+        {
+          return true; // Also success if layer is consuming the hit
+        }
       }
     }
   }
@@ -398,9 +424,10 @@ bool HitTestRenderTask( LayerList& layers,
 
 /**
  * Iterate through RenderTaskList and perform hit test.
+ *
+ * @return true if we have a hit, false otherwise
  */
-
-void HitTestForEachRenderTask( LayerList& layers,
+bool HitTestForEachRenderTask( LayerList& layers,
                                RenderTaskList& taskList,
                                const Vector2& screenCoordinates,
                                Results& results,
@@ -432,8 +459,8 @@ void HitTestForEachRenderTask( LayerList& layers,
 
     if ( HitTestRenderTask( layers, renderTask, screenCoordinates, results, hitCheck ) )
     {
-      // Exit when an actor is hit
-      return; // don't bother checking off screen tasks
+      // Return true when an actor is hit (or layer in our render-task consumes the hit)
+      return true; // don't bother checking off screen tasks
     }
   }
 
@@ -457,11 +484,12 @@ void HitTestForEachRenderTask( LayerList& layers,
 
       if ( HitTestRenderTask( layers, renderTask, screenCoordinates, results, hitCheck ) )
       {
-        // Exit when an actor is hit
-        break;
+        // Return true when an actor is hit (or a layer in our render-task consumes the hit)
+        return true;
       }
     }
   }
+  return false;
 }
 
 } // unnamed namespace
@@ -474,14 +502,17 @@ void HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgor
 
   Results hitTestResults;
   HitTestFunctionWrapper hitTestFunctionWrapper( func );
-  HitTestForEachRenderTask( layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper );
-
-  results.actor = hitTestResults.actor;
-  results.actorCoordinates = hitTestResults.actorCoordinates;
+  if (  HitTestForEachRenderTask( layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+  {
+    results.actor = hitTestResults.actor;
+    results.actorCoordinates = hitTestResults.actorCoordinates;
+  }
 }
 
 void HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results, HitTestInterface& hitTestInterface )
 {
+  bool hit = false;
+
   // Hit-test the system-overlay actors first
   SystemOverlay* systemOverlay = stage.GetSystemOverlayInternal();
 
@@ -490,11 +521,11 @@ void HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results,
     RenderTaskList& overlayTaskList = systemOverlay->GetOverlayRenderTasks();
     LayerList& overlayLayerList = systemOverlay->GetLayerList();
 
-    HitTestForEachRenderTask( overlayLayerList, overlayTaskList, screenCoordinates, results, hitTestInterface );
+    hit = HitTestForEachRenderTask( overlayLayerList, overlayTaskList, screenCoordinates, results, hitTestInterface );
   }
 
   // Hit-test the regular on-stage actors
-  if ( !results.actor )
+  if ( !hit )
   {
     RenderTaskList& taskList = stage.GetRenderTaskList();
     LayerList& layerList = stage.GetLayerList();
@@ -514,9 +545,11 @@ void HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordin
 {
   Results hitTestResults;
   HitTestFunctionWrapper hitTestFunctionWrapper( func );
-  HitTestRenderTask( stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper );
-  results.actor = hitTestResults.actor;
-  results.actorCoordinates = hitTestResults.actorCoordinates;
+  if ( HitTestRenderTask( stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+  {
+    results.actor = hitTestResults.actor;
+    results.actorCoordinates = hitTestResults.actorCoordinates;
+  }
 }
 
 } // namespace HitTestAlgorithm
index 21d8da0..1225900 100644 (file)
@@ -28,6 +28,8 @@ namespace Dali
 namespace Internal
 {
 
+class Layer;
+
 /**
  * This namespace is provided for application developers to do hit test for the actors.
  */
@@ -51,16 +53,34 @@ struct HitTestInterface
 {
   /**
    * Called by the hit-test algorithm to determine whether the actor is hittable or not.
+   *
    * @param[in] actor Raw pointer to an Actor object.
+   *
+   * @return true if actor is hittable, false otherwise.
    */
   virtual bool IsActorHittable( Actor* actor ) = 0;
 
   /**
    * Called by the hit-test algorithm to determine whether the algorithm should descend the actor's
    * hierarchy (and hit-test its children as well).
+   *
    * @param[in] actor Raw pointer to an Actor object.
+   *
+   * @return true if we should descend the actor's hierarchy, false otherwise.
    */
   virtual bool DescendActorHierarchy( Actor* actor ) = 0;
+
+  /**
+   * Called by the hit-test algorithm to determine whether the layer specified consumes the hit
+   * regardless of whether an actor in the layer requires it or not.
+   *
+   * @note If true is returned, then no layers behind this layer will be hit-test.
+   *
+   * @param[in] layer Raw pointer to a Layer object.
+   *
+   * @return true if the layer should consume the hit, false otherwise.
+   */
+  virtual bool DoesLayerConsumeHit( Layer* layer ) = 0;
 };
 
 /**
index 15cb9a0..bfaa85e 100644 (file)
@@ -143,6 +143,16 @@ void Layer::SetSortFunction(SortFunctionType function)
   GetImplementation(*this).SetSortFunction(function);
 }
 
+void Layer::SetTouchConsumed( bool consume )
+{
+  GetImplementation( *this ).SetTouchConsumed( consume );
+}
+
+bool Layer::IsTouchConsumed() const
+{
+  return GetImplementation( *this ).IsTouchConsumed();
+}
+
 Layer::Layer(Internal::Layer* internal)
 : Actor(internal)
 {