From: Adeel Kazmi Date: Wed, 4 Jun 2014 12:59:57 +0000 (+0100) Subject: (Gestures) Each actor is now aware of what gestures it requires which is used when... X-Git-Tag: dali_1.0.0~46 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f8c53e205507ddfc08ef0bf3a39f1afb81eb05a2;p=platform%2Fcore%2Fuifw%2Fdali-core.git (Gestures) Each actor is now aware of what gestures it requires which is used when hit-testing [problem] Cannot tap anything behind invisible status bar. [cause] Status bar consumes all gestures even though it doesn't require them. [solution] Change the system so that actors are aware of what gestures they have so it is possible to gesture actors behind the status bar. Change-Id: I713c907c764445263362803a98af0fa514ffd955 Signed-off-by: Adeel Kazmi --- diff --git a/automated-tests/src/dali/CMakeLists.txt b/automated-tests/src/dali/CMakeLists.txt index 8da4347..647ce4a 100644 --- a/automated-tests/src/dali/CMakeLists.txt +++ b/automated-tests/src/dali/CMakeLists.txt @@ -20,7 +20,6 @@ SET(TC_SOURCES utc-Dali-Constraint.cpp utc-Dali-CustomActor.cpp utc-Dali-Degree.cpp - utc-Dali-EventProcessing.cpp utc-Dali-Font.cpp utc-Dali-FontParameters.cpp utc-Dali-FrameBufferImage.cpp diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-touch-utils.h b/automated-tests/src/dali/dali-test-suite-utils/test-touch-utils.h new file mode 100644 index 0000000..f939aa3 --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-touch-utils.h @@ -0,0 +1,77 @@ +#ifndef _TEST_TOUCH_UTILS_H_ +#define _TEST_TOUCH_UTILS_H_ + +// +// Copyright (c) 2014 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include + +namespace Dali +{ + +// Data for touch events +struct TouchEventData +{ + TouchEventData() + : functorCalled(false), + receivedTouch(), + touchActor() + { + } + + void Reset() + { + functorCalled = false; + + receivedTouch.points.clear(); + receivedTouch.time = 0; + + touchActor = NULL; + } + + bool functorCalled; + TouchEvent receivedTouch; + Actor touchActor; +}; + +// Functor that sets the data when called +struct TouchEventDataFunctor +{ + TouchEventDataFunctor(TouchEventData& data) : touchEventData(data) { } + + bool operator()(Actor actor, const TouchEvent& touch) + { + touchEventData.functorCalled = true; + touchEventData.touchActor = actor; + touchEventData.receivedTouch = touch; + return false; + } + + // Generate a touch-event + Integration::TouchEvent GenerateSingleTouch( TouchPoint::State state, Vector2 screenPosition ) const + { + Integration::TouchEvent touchEvent; + touchEvent.points.push_back( TouchPoint ( 0, state, screenPosition.x, screenPosition.y ) ); + return touchEvent; + } + + TouchEventData& touchEventData; +}; + + +} // namespace Dali + +#endif // _TEST_TOUCH_UTILS_H_ diff --git a/automated-tests/src/dali/tct-dali-core.h b/automated-tests/src/dali/tct-dali-core.h index 7a7d126..0babbb3 100644 --- a/automated-tests/src/dali/tct-dali-core.h +++ b/automated-tests/src/dali/tct-dali-core.h @@ -31,8 +31,6 @@ extern void custom_actor_test_startup(void); extern void custom_actor_test_cleanup(void); extern void utc_dali_degree_startup(void); extern void utc_dali_degree_cleanup(void); -extern void utc_dali_event_processing_startup(void); -extern void utc_dali_event_processing_cleanup(void); extern void utc_dali_font_startup(void); extern void utc_dali_font_cleanup(void); extern void utc_dali_font_parameters_startup(void); @@ -585,8 +583,6 @@ extern int UtcDaliDegreeCastOperators01(void); extern int UtcDaliDegreeCastOperatorEquals(void); extern int UtcDaliDegreeCastOperatorNotEquals(void); extern int UtcDaliDegreeCastOperatorLessThan(void); -extern int UtcDaliInvalidEvent(void); -extern int UtcDaliInvalidGesture(void); extern int UtcDaliFontNew01(void); extern int UtcDaliFontNew02(void); extern int UtcDaliFontNew03(void); @@ -773,6 +769,8 @@ extern int UtcDaliLongPressGestureDetachAfterStarted(void); extern int UtcDaliLongPressGestureActorUnstaged(void); extern int UtcDaliLongPressGestureActorStagedAndDestroyed(void); extern int UtcDaliLongPressGestureSystemOverlay(void); +extern int UtcDaliLongPressGestureBehindTouchableSystemOverlay(void); +extern int UtcDaliLongPressGestureTouchBehindGesturedSystemOverlay(void); extern int UtcDaliMaterialNew01(void); extern int UtcDaliMaterialDownCast(void); extern int UtcDaliMaterialSettersAndGetters(void); @@ -869,6 +867,8 @@ extern int UtcDaliPanGestureEmitIncorrectState(void); extern int UtcDaliPanGestureActorUnstaged(void); extern int UtcDaliPanGestureActorStagedAndDestroyed(void); extern int UtcDaliPanGestureSystemOverlay(void); +extern int UtcDaliPanGestureBehindTouchableSystemOverlay(void); +extern int UtcDaliPanGestureTouchBehindGesturedSystemOverlay(void); extern int UtcDaliPanGestureAngleHandling(void); extern int UtcDaliPanGestureAngleOutOfRange(void); extern int UtcDaliPanGestureAngleProcessing(void); @@ -901,6 +901,8 @@ extern int UtcDaliPinchGestureEmitIncorrectStatePossible(void); extern int UtcDaliPinchGestureActorUnstaged(void); extern int UtcDaliPinchGestureActorStagedAndDestroyed(void); extern int UtcDaliPinchGestureSystemOverlay(void); +extern int UtcDaliPinchGestureBehindTouchableSystemOverlay(void); +extern int UtcDaliPinchGestureTouchBehindGesturedSystemOverlay(void); extern int UtcDaliPixelHasAlpha(void); extern int UtcDaliPixelGetBytesPerPixel(void); extern int UtcDaliPixelGetAlphaOffsetAndMask(void); @@ -1169,6 +1171,8 @@ extern int UtcDaliTapGesturePossibleCancelled(void); extern int UtcDaliTapGestureDetectorRemovedWhilePossible(void); extern int UtcDaliTapGestureActorRemovedWhilePossible(void); extern int UtcDaliTapGestureSystemOverlay(void); +extern int UtcDaliTapGestureBehindTouchableSystemOverlay(void); +extern int UtcDaliTapGestureTouchBehindGesturedSystemOverlay(void); extern int UtcDaliTextConstructor(void); extern int UtcDaliTextCopyConstructor(void); extern int UtcDaliTextAssignmentOperator(void); @@ -1794,8 +1798,6 @@ testcase tc_array[] = { {"UtcDaliDegreeCastOperatorEquals", UtcDaliDegreeCastOperatorEquals, utc_dali_degree_startup, utc_dali_degree_cleanup}, {"UtcDaliDegreeCastOperatorNotEquals", UtcDaliDegreeCastOperatorNotEquals, utc_dali_degree_startup, utc_dali_degree_cleanup}, {"UtcDaliDegreeCastOperatorLessThan", UtcDaliDegreeCastOperatorLessThan, utc_dali_degree_startup, utc_dali_degree_cleanup}, - {"UtcDaliInvalidEvent", UtcDaliInvalidEvent, utc_dali_event_processing_startup, utc_dali_event_processing_cleanup}, - {"UtcDaliInvalidGesture", UtcDaliInvalidGesture, utc_dali_event_processing_startup, utc_dali_event_processing_cleanup}, {"UtcDaliFontNew01", UtcDaliFontNew01, utc_dali_font_startup, utc_dali_font_cleanup}, {"UtcDaliFontNew02", UtcDaliFontNew02, utc_dali_font_startup, utc_dali_font_cleanup}, {"UtcDaliFontNew03", UtcDaliFontNew03, utc_dali_font_startup, utc_dali_font_cleanup}, @@ -1982,6 +1984,8 @@ testcase tc_array[] = { {"UtcDaliLongPressGestureActorUnstaged", UtcDaliLongPressGestureActorUnstaged, utc_dali_long_press_gesture_detector_startup, utc_dali_long_press_gesture_detector_cleanup}, {"UtcDaliLongPressGestureActorStagedAndDestroyed", UtcDaliLongPressGestureActorStagedAndDestroyed, utc_dali_long_press_gesture_detector_startup, utc_dali_long_press_gesture_detector_cleanup}, {"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}, {"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}, @@ -2078,6 +2082,8 @@ testcase tc_array[] = { {"UtcDaliPanGestureActorUnstaged", UtcDaliPanGestureActorUnstaged, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup}, {"UtcDaliPanGestureActorStagedAndDestroyed", UtcDaliPanGestureActorStagedAndDestroyed, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup}, {"UtcDaliPanGestureSystemOverlay", UtcDaliPanGestureSystemOverlay, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup}, + {"UtcDaliPanGestureBehindTouchableSystemOverlay", UtcDaliPanGestureBehindTouchableSystemOverlay, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup}, + {"UtcDaliPanGestureTouchBehindGesturedSystemOverlay", UtcDaliPanGestureTouchBehindGesturedSystemOverlay, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup}, {"UtcDaliPanGestureAngleHandling", UtcDaliPanGestureAngleHandling, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup}, {"UtcDaliPanGestureAngleOutOfRange", UtcDaliPanGestureAngleOutOfRange, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup}, {"UtcDaliPanGestureAngleProcessing", UtcDaliPanGestureAngleProcessing, utc_dali_pan_gesture_detector_startup, utc_dali_pan_gesture_detector_cleanup}, @@ -2110,6 +2116,8 @@ testcase tc_array[] = { {"UtcDaliPinchGestureActorUnstaged", UtcDaliPinchGestureActorUnstaged, utc_dali_pinch_gesture_detector_startup, utc_dali_pinch_gesture_detector_cleanup}, {"UtcDaliPinchGestureActorStagedAndDestroyed", UtcDaliPinchGestureActorStagedAndDestroyed, utc_dali_pinch_gesture_detector_startup, utc_dali_pinch_gesture_detector_cleanup}, {"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}, {"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}, @@ -2378,6 +2386,8 @@ testcase tc_array[] = { {"UtcDaliTapGestureDetectorRemovedWhilePossible", UtcDaliTapGestureDetectorRemovedWhilePossible, utc_dali_tap_gesture_detector_startup, utc_dali_tap_gesture_detector_cleanup}, {"UtcDaliTapGestureActorRemovedWhilePossible", UtcDaliTapGestureActorRemovedWhilePossible, utc_dali_tap_gesture_detector_startup, utc_dali_tap_gesture_detector_cleanup}, {"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}, {"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}, diff --git a/automated-tests/src/dali/utc-Dali-EventProcessing.cpp b/automated-tests/src/dali/utc-Dali-EventProcessing.cpp deleted file mode 100644 index 62e6bf96..0000000 --- a/automated-tests/src/dali/utc-Dali-EventProcessing.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include - -#include -#include -#include -#include -#include - -using namespace Dali; - -void utc_dali_event_processing_startup(void) -{ - test_return_value = TET_UNDEF; -} - -void utc_dali_event_processing_cleanup(void) -{ - test_return_value = TET_PASS; -} - -namespace -{ - -struct InvalidEvent : public Integration::Event -{ - InvalidEvent() : Event( Event::Type(-1000) ) {} - ~InvalidEvent() {} -}; - -struct InvalidGesture : public Integration::GestureEvent -{ - InvalidGesture() : GestureEvent( Gesture::Type(-1000), Gesture::Clear ) {} - ~InvalidGesture() {} -}; - -} // anon namespace - -int UtcDaliInvalidEvent(void) -{ - TestApplication application; - - try - { - InvalidEvent event; - application.ProcessEvent( event ); - tet_result( TET_FAIL ); - } - catch ( Dali::DaliException& e ) - { - DALI_TEST_ASSERT( e, "false", TEST_LOCATION ); - } - END_TEST; -} - -int UtcDaliInvalidGesture(void) -{ - TestApplication application; - - try - { - InvalidGesture event; - application.ProcessEvent( event ); - tet_result( TET_FAIL ); - } - catch ( Dali::DaliException& e ) - { - DALI_TEST_ASSERT( e, "false", TEST_LOCATION ); - } - END_TEST; -} diff --git a/automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp index f462950..ae64bd1 100644 --- a/automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace Dali; @@ -1261,6 +1262,114 @@ int UtcDaliLongPressGestureSystemOverlay(void) Vector2 screenCoords( 50.0f, 50.0f ); application.ProcessEvent( GenerateLongPress( Gesture::Possible, 1u, screenCoords ) ); application.ProcessEvent( GenerateLongPress( Gesture::Started, 1u, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliLongPressGestureBehindTouchableSystemOverlay(void) +{ + TestApplication application; + Dali::Integration::Core& core = application.GetCore(); + Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() ); + systemOverlay.GetOverlayRenderTasks().CreateTask(); + + // SystemOverlay actor + Actor systemOverlayActor = Actor::New(); + systemOverlayActor.SetSize(100.0f, 100.0f); + systemOverlayActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + systemOverlay.Add(systemOverlayActor); + + // Stage actor + Actor stageActor = Actor::New(); + stageActor.SetSize(100.0f, 100.0f); + stageActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add(stageActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set system-overlay actor to touchable + TouchEventData touchData; + TouchEventDataFunctor touchFunctor( touchData ); + systemOverlayActor.TouchedSignal().Connect(&application, touchFunctor); + + // Set stage actor to receive the gesture + SignalData data; + GestureReceivedFunctor functor(data); + + LongPressGestureDetector detector = LongPressGestureDetector::New(); + detector.Attach(stageActor); + detector.DetectedSignal().Connect(&application, functor); + + // Start long press within the two actors' area + Vector2 screenCoords( 50.0f, 50.0f ); + application.ProcessEvent( GenerateLongPress( Gesture::Possible, 1u, screenCoords ) ); + application.ProcessEvent( GenerateLongPress( Gesture::Started, 1u, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( false, touchData.functorCalled, TEST_LOCATION ); + + data.Reset(); + touchData.Reset(); + + // Do touch in the same area + application.ProcessEvent( touchFunctor.GenerateSingleTouch( TouchPoint::Down, screenCoords ) ); DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( true, touchData.functorCalled, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLongPressGestureTouchBehindGesturedSystemOverlay(void) +{ + TestApplication application; + Dali::Integration::Core& core = application.GetCore(); + Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() ); + systemOverlay.GetOverlayRenderTasks().CreateTask(); + + // SystemOverlay actor + Actor systemOverlayActor = Actor::New(); + systemOverlayActor.SetSize(100.0f, 100.0f); + systemOverlayActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + systemOverlay.Add(systemOverlayActor); + + // Stage actor + Actor stageActor = Actor::New(); + stageActor.SetSize(100.0f, 100.0f); + stageActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add(stageActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set stage actor to touchable + TouchEventData touchData; + TouchEventDataFunctor touchFunctor( touchData ); + stageActor.TouchedSignal().Connect(&application, touchFunctor); + + // Set system-overlay actor to have the gesture + SignalData data; + GestureReceivedFunctor functor(data); + + LongPressGestureDetector detector = LongPressGestureDetector::New(); + detector.Attach(systemOverlayActor); + detector.DetectedSignal().Connect(&application, functor); + + // Start long press within the two actors' area + Vector2 screenCoords( 50.0f, 50.0f ); + application.ProcessEvent( GenerateLongPress( Gesture::Possible, 1u, screenCoords ) ); + application.ProcessEvent( GenerateLongPress( Gesture::Started, 1u, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( false, touchData.functorCalled, TEST_LOCATION ); + + data.Reset(); + touchData.Reset(); + + // Do touch in the same area + application.ProcessEvent( touchFunctor.GenerateSingleTouch( TouchPoint::Down, screenCoords ) ); + DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( true, touchData.functorCalled, TEST_LOCATION ); + END_TEST; } diff --git a/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp index e91e71d..c0af9de 100644 --- a/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include using namespace Dali; @@ -41,7 +43,7 @@ namespace typedef Dali::PanGestureDetector::AngleContainer::size_type AngleSizeType; -// Stores data that is populated in the callback and will be read by the TET cases +// Stores data that is populated in the callback and will be read by the test cases struct SignalData { SignalData() @@ -1532,7 +1534,121 @@ int UtcDaliPanGestureSystemOverlay(void) // Start pan within the actor's area application.ProcessEvent( GeneratePan( Gesture::Possible, screenCoordsStart, screenCoordsEnd, 10 ) ); application.ProcessEvent( GeneratePan( Gesture::Started, screenCoordsStart, screenCoordsEnd, 10 ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliPanGestureBehindTouchableSystemOverlay(void) +{ + TestApplication application; + Dali::Integration::Core& core = application.GetCore(); + Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() ); + systemOverlay.GetOverlayRenderTasks().CreateTask(); + + // SystemOverlay actor + Actor systemOverlayActor = Actor::New(); + systemOverlayActor.SetSize(100.0f, 100.0f); + systemOverlayActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + systemOverlay.Add(systemOverlayActor); + + // Stage actor + Actor stageActor = Actor::New(); + stageActor.SetSize(100.0f, 100.0f); + stageActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add(stageActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set system-overlay actor to touchable + TouchEventData touchData; + TouchEventDataFunctor touchFunctor( touchData ); + systemOverlayActor.TouchedSignal().Connect(&application, touchFunctor); + + // Set stage actor to receive the gesture + SignalData data; + GestureReceivedFunctor functor(data); + + PanGestureDetector detector = PanGestureDetector::New(); + detector.Attach(stageActor); + detector.DetectedSignal().Connect(&application, functor); + + Vector2 screenCoordsStart( 10.0f, 20.0f ); + Vector2 screenCoordsEnd( 20.0f, 20.0f ); + + // Start pan within the two actors' area + application.ProcessEvent( GeneratePan( Gesture::Possible, screenCoordsStart, screenCoordsEnd, 10 ) ); + application.ProcessEvent( GeneratePan( Gesture::Started, screenCoordsStart, screenCoordsEnd, 10 ) ); + application.ProcessEvent( GeneratePan( Gesture::Finished, screenCoordsStart, screenCoordsEnd, 10 ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( false, touchData.functorCalled, TEST_LOCATION ); + + data.Reset(); + touchData.Reset(); + + // Do touch in the same area + application.ProcessEvent( touchFunctor.GenerateSingleTouch( TouchPoint::Down, screenCoordsStart ) ); DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( true, touchData.functorCalled, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliPanGestureTouchBehindGesturedSystemOverlay(void) +{ + TestApplication application; + Dali::Integration::Core& core = application.GetCore(); + Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() ); + systemOverlay.GetOverlayRenderTasks().CreateTask(); + + // SystemOverlay actor + Actor systemOverlayActor = Actor::New(); + systemOverlayActor.SetSize(100.0f, 100.0f); + systemOverlayActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + systemOverlay.Add(systemOverlayActor); + + // Stage actor + Actor stageActor = Actor::New(); + stageActor.SetSize(100.0f, 100.0f); + stageActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add(stageActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set stage actor to touchable + TouchEventData touchData; + TouchEventDataFunctor touchFunctor( touchData ); + stageActor.TouchedSignal().Connect(&application, touchFunctor); + + // Set system-overlay actor to have the gesture + SignalData data; + GestureReceivedFunctor functor(data); + + PanGestureDetector detector = PanGestureDetector::New(); + detector.Attach(systemOverlayActor); + detector.DetectedSignal().Connect(&application, functor); + + Vector2 screenCoordsStart( 10.0f, 20.0f ); + Vector2 screenCoordsEnd( 20.0f, 20.0f ); + + // Start pan within the two actors' area + application.ProcessEvent( GeneratePan( Gesture::Possible, screenCoordsStart, screenCoordsEnd, 10 ) ); + application.ProcessEvent( GeneratePan( Gesture::Started, screenCoordsStart, screenCoordsEnd, 10 ) ); + application.ProcessEvent( GeneratePan( Gesture::Finished, screenCoordsStart, screenCoordsEnd, 10 ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( false, touchData.functorCalled, TEST_LOCATION ); + + data.Reset(); + touchData.Reset(); + + // Do touch in the same area + application.ProcessEvent( touchFunctor.GenerateSingleTouch( TouchPoint::Down, screenCoordsStart ) ); + DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( true, touchData.functorCalled, TEST_LOCATION ); + END_TEST; } @@ -1885,6 +2001,7 @@ int UtcDaliPanGestureSetProperties(void) { TestApplication application; TestRenderController& renderController( application.GetRenderController() ); + Integration::SetPanGesturePredictionMode(0); Actor actor = Actor::New(); actor.SetSize(100.0f, 100.0f); @@ -1938,6 +2055,7 @@ int UtcDaliPanGestureSetProperties(void) int UtcDaliPanGestureSetPropertiesAlreadyPanning(void) { TestApplication application; + Integration::SetPanGesturePredictionMode(0); Actor actor = Actor::New(); actor.SetSize(100.0f, 100.0f); diff --git a/automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp index af87180..5ee3c2f 100644 --- a/automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace Dali; @@ -1180,6 +1181,120 @@ int UtcDaliPinchGestureSystemOverlay(void) // Start pan within the actor's area application.ProcessEvent( GeneratePinch( Gesture::Started, scale, speed, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliPinchGestureBehindTouchableSystemOverlay(void) +{ + TestApplication application; + Dali::Integration::Core& core = application.GetCore(); + Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() ); + systemOverlay.GetOverlayRenderTasks().CreateTask(); + + // SystemOverlay actor + Actor systemOverlayActor = Actor::New(); + systemOverlayActor.SetSize(100.0f, 100.0f); + systemOverlayActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + systemOverlay.Add(systemOverlayActor); + + // Stage actor + Actor stageActor = Actor::New(); + stageActor.SetSize(100.0f, 100.0f); + stageActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add(stageActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set system-overlay actor to touchable + TouchEventData touchData; + TouchEventDataFunctor touchFunctor( touchData ); + systemOverlayActor.TouchedSignal().Connect(&application, touchFunctor); + + // Set stage actor to receive the gesture + SignalData data; + GestureReceivedFunctor functor(data); + + PinchGestureDetector detector = PinchGestureDetector::New(); + detector.Attach(stageActor); + detector.DetectedSignal().Connect(&application, functor); + + Vector2 screenCoords( 50.0f, 50.0f ); + float scale ( 10.0f ); + float speed ( 50.0f ); + + // Start pinch within the two actors' area + application.ProcessEvent( GeneratePinch( Gesture::Started, scale, speed, screenCoords ) ); + application.ProcessEvent( GeneratePinch( Gesture::Finished, scale, speed, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( false, touchData.functorCalled, TEST_LOCATION ); + + data.Reset(); + touchData.Reset(); + + // Do touch in the same area + application.ProcessEvent( touchFunctor.GenerateSingleTouch( TouchPoint::Down, screenCoords ) ); DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( true, touchData.functorCalled, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliPinchGestureTouchBehindGesturedSystemOverlay(void) +{ + TestApplication application; + Dali::Integration::Core& core = application.GetCore(); + Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() ); + systemOverlay.GetOverlayRenderTasks().CreateTask(); + + // SystemOverlay actor + Actor systemOverlayActor = Actor::New(); + systemOverlayActor.SetSize(100.0f, 100.0f); + systemOverlayActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + systemOverlay.Add(systemOverlayActor); + + // Stage actor + Actor stageActor = Actor::New(); + stageActor.SetSize(100.0f, 100.0f); + stageActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add(stageActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set stage actor to touchable + TouchEventData touchData; + TouchEventDataFunctor touchFunctor( touchData ); + stageActor.TouchedSignal().Connect(&application, touchFunctor); + + // Set system-overlay actor to have the gesture + SignalData data; + GestureReceivedFunctor functor(data); + + PinchGestureDetector detector = PinchGestureDetector::New(); + detector.Attach(systemOverlayActor); + detector.DetectedSignal().Connect(&application, functor); + + Vector2 screenCoords( 50.0f, 50.0f ); + float scale ( 10.0f ); + float speed ( 50.0f ); + + // Start pinch within the two actors' area + application.ProcessEvent( GeneratePinch( Gesture::Started, scale, speed, screenCoords ) ); + application.ProcessEvent( GeneratePinch( Gesture::Finished, scale, speed, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( false, touchData.functorCalled, TEST_LOCATION ); + + data.Reset(); + touchData.Reset(); + + // Do touch in the same area + application.ProcessEvent( touchFunctor.GenerateSingleTouch( TouchPoint::Down, screenCoords ) ); + DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( true, touchData.functorCalled, TEST_LOCATION ); + END_TEST; } diff --git a/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp index e26588e..58dc606 100644 --- a/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace Dali; @@ -1167,6 +1168,116 @@ int UtcDaliTapGestureSystemOverlay(void) // Do a tap inside actor's area application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, screenCoords ) ); application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliTapGestureBehindTouchableSystemOverlay(void) +{ + TestApplication application; + Dali::Integration::Core& core = application.GetCore(); + Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() ); + systemOverlay.GetOverlayRenderTasks().CreateTask(); + + // SystemOverlay actor + Actor systemOverlayActor = Actor::New(); + systemOverlayActor.SetSize(100.0f, 100.0f); + systemOverlayActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + systemOverlay.Add(systemOverlayActor); + + // Stage actor + Actor stageActor = Actor::New(); + stageActor.SetSize(100.0f, 100.0f); + stageActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add(stageActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set system-overlay actor to touchable + TouchEventData touchData; + TouchEventDataFunctor touchFunctor( touchData ); + systemOverlayActor.TouchedSignal().Connect(&application, touchFunctor); + + // Set stage actor to receive the gesture + SignalData data; + GestureReceivedFunctor functor(data); + + TapGestureDetector detector = TapGestureDetector::New(); + detector.Attach(stageActor); + detector.DetectedSignal().Connect(&application, functor); + + Vector2 screenCoords( 50.0f, 50.0f ); + + // Do a tap inside both actors' area + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, screenCoords ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( false, touchData.functorCalled, TEST_LOCATION ); + + data.Reset(); + touchData.Reset(); + + // Do touch in the same area + application.ProcessEvent( touchFunctor.GenerateSingleTouch( TouchPoint::Down, screenCoords ) ); + DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( true, touchData.functorCalled, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliTapGestureTouchBehindGesturedSystemOverlay(void) +{ + TestApplication application; + Dali::Integration::Core& core = application.GetCore(); + Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() ); + systemOverlay.GetOverlayRenderTasks().CreateTask(); + + // SystemOverlay actor + Actor systemOverlayActor = Actor::New(); + systemOverlayActor.SetSize(100.0f, 100.0f); + systemOverlayActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + systemOverlay.Add(systemOverlayActor); + + // Stage actor + Actor stageActor = Actor::New(); + stageActor.SetSize(100.0f, 100.0f); + stageActor.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add(stageActor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set stage actor to touchable + TouchEventData touchData; + TouchEventDataFunctor touchFunctor( touchData ); + stageActor.TouchedSignal().Connect(&application, touchFunctor); + + // Set system-overlay actor to have the gesture + SignalData data; + GestureReceivedFunctor functor(data); + + TapGestureDetector detector = TapGestureDetector::New(); + detector.Attach(systemOverlayActor); + detector.DetectedSignal().Connect(&application, functor); + + Vector2 screenCoords( 50.0f, 50.0f ); + + // Do a tap inside both actors' area + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, screenCoords ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, screenCoords ) ); + DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( false, touchData.functorCalled, TEST_LOCATION ); + + data.Reset(); + touchData.Reset(); + + // Do touch in the same area + application.ProcessEvent( touchFunctor.GenerateSingleTouch( TouchPoint::Down, screenCoords ) ); DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION ); + DALI_TEST_EQUALS( true, touchData.functorCalled, TEST_LOCATION ); + END_TEST; } diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 5ce5cb6..8c3116b 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -56,6 +56,11 @@ #include #endif +#include +#include +#include +#include + using Dali::Internal::SceneGraph::Node; using Dali::Internal::SceneGraph::AnimatableProperty; using Dali::Internal::SceneGraph::PropertyBase; @@ -176,6 +181,90 @@ namespace Internal unsigned int Actor::mActorCounter = 0; ActorContainer Actor::mNullChildren; +// Encapsulate actor related gesture information +struct GestureData +{ + /** + * Constructor + */ + GestureData() + : gesturesRequired( Gesture::Type( 0 ) ), + panDetectors( NULL ), + pinchDetectors( NULL ), + longPressDetectors( NULL ), + tapDetectors( NULL ) + { + } + + /** + * Destructor + */ + ~GestureData() + { + delete panDetectors; + delete pinchDetectors; + delete longPressDetectors; + delete tapDetectors; + } + + /** + * Checks if the containers in GestureData are empty + */ + bool Empty() const + { + return !panDetectors && + !pinchDetectors && + !longPressDetectors && + !tapDetectors; + } + + /** + * Template to add a detector to the appropriate container. Dynamically allocates the container + * only if it is used. + */ + template< typename DetectorType, typename ContainerType > + void AddDetector( ContainerType*& containerPtr, GestureDetector* detector ) + { + if ( NULL == containerPtr ) + { + containerPtr = new ContainerType; + } + + containerPtr->push_back( static_cast< DetectorType* >( detector ) ); + gesturesRequired = Gesture::Type( gesturesRequired | detector->GetType() ); + } + + /** + * Template to remove a detector from the appropriate container. Deletes the container if it is + * no longer required. + */ + template< typename ContainerType > + void RemoveDetector( ContainerType*& containerPtr, GestureDetector* detector ) + { + if ( NULL != containerPtr ) + { + ContainerType& container( *containerPtr ); + typename ContainerType::iterator match( std::remove( container.begin(), container.end(), detector ) ); + DALI_ASSERT_DEBUG( match != container.end() && "Actor does not have the detector" ); + container.erase( match, container.end() ); + + if ( container.empty() ) + { + gesturesRequired = Gesture::Type( gesturesRequired & ~detector->GetType() ); + delete containerPtr; + containerPtr = NULL; + } + } + } + + Gesture::Type gesturesRequired; + + PanGestureDetectorContainer* panDetectors; + PinchGestureDetectorContainer* pinchDetectors; + LongPressGestureDetectorContainer* longPressDetectors; + TapGestureDetectorContainer* tapDetectors; +}; + #ifdef DYNAMICS_SUPPORT // Encapsulate actor related dynamics data @@ -1886,6 +1975,91 @@ bool Actor::IsHittable() const IsNodeConnected(); } +void Actor::AddGestureDetector( GestureDetector& detector ) +{ + if ( NULL == mGestureData ) + { + mGestureData = new GestureData; + } + + const Gesture::Type type( detector.GetType() ); + switch ( type ) + { + case Gesture::Pan: + { + mGestureData->AddDetector< PanGestureDetector, PanGestureDetectorContainer >( mGestureData->panDetectors, &detector ); + break; + } + + case Gesture::Pinch: + { + mGestureData->AddDetector< PinchGestureDetector, PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector ); + break; + } + + case Gesture::LongPress: + { + mGestureData->AddDetector< LongPressGestureDetector, LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector ); + break; + } + + case Gesture::Tap: + { + mGestureData->AddDetector< TapGestureDetector, TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector ); + break; + } + } +} + +void Actor::RemoveGestureDetector( GestureDetector& detector ) +{ + if ( NULL != mGestureData ) + { + switch ( detector.GetType() ) + { + case Gesture::Pan: + { + mGestureData->RemoveDetector< PanGestureDetectorContainer >( mGestureData->panDetectors, &detector ); + break; + } + + case Gesture::Pinch: + { + mGestureData->RemoveDetector< PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector ); + break; + } + + case Gesture::LongPress: + { + mGestureData->RemoveDetector< LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector ); + break; + } + + case Gesture::Tap: + { + mGestureData->RemoveDetector< TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector ); + break; + } + } + + if ( mGestureData->Empty() ) + { + delete mGestureData; + mGestureData = NULL; + } + } +} + +bool Actor::IsGestureRequred( Gesture::Type type ) const +{ + bool required( false ); + if ( NULL != mGestureData ) + { + required = type & mGestureData->gesturesRequired; + } + return required; +} + bool Actor::EmitTouchEventSignal(const TouchEvent& event) { bool consumed = false; @@ -1993,6 +2167,7 @@ Actor::Actor( DerivedType derivedType ) #ifdef DYNAMICS_SUPPORT mDynamicsData( NULL ), #endif + mGestureData( NULL ), mAttachment(), mShaderEffect(), mName(), @@ -2073,6 +2248,9 @@ Actor::~Actor() delete mDynamicsData; #endif + // Cleanup optional gesture data + delete mGestureData; + // Cleanup optional parent origin and anchor delete mParentOrigin; delete mAnchorPoint; diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index d694054..239b162 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -48,9 +49,11 @@ namespace Internal { class Actor; +class GestureDetector; class RenderTask; class ShaderEffect; struct DynamicsData; +struct GestureData; typedef IntrusivePtr ActorPtr; typedef IntrusivePtr ShaderEffectPtr; @@ -940,6 +943,30 @@ public: */ bool IsHittable() const; + // Gestures + + /** + * Adds a gesture detector to the actor so that the actor is aware that it requires this type of + * gesture. + * @param[in] detector The detector being added. + * @note A raw pointer to the detector is stored, so the detector MUST remove itself when it is + * destroyed using RemoveGestureDetector() + */ + void AddGestureDetector( GestureDetector& detector ); + + /** + * Removes a previously added gesture detector from the actor. If no more gesture detectors of + * this type are registered with this actor then the actor will no longer be hit-tested for that + * gesture. + * @param[in] detector The detector to remove. + */ + void RemoveGestureDetector( GestureDetector& detector ); + + /** + * Queries whether the actor requires the gesture type. + * @param[in] type The gesture type. + */ + bool IsGestureRequred( Gesture::Type type ) const; // Signals @@ -1304,6 +1331,8 @@ protected: DynamicsData* mDynamicsData; ///< optional physics data #endif + GestureData* mGestureData; /// Optional Gesture data. Only created when actor requires gestures + ActorAttachmentPtr mAttachment; ///< Optional referenced attachment ShaderEffectPtr mShaderEffect; ///< Optional referenced shader effect diff --git a/dali/internal/event/events/gesture-detector-impl.cpp b/dali/internal/event/events/gesture-detector-impl.cpp index d2dc891..bd23375 100644 --- a/dali/internal/event/events/gesture-detector-impl.cpp +++ b/dali/internal/event/events/gesture-detector-impl.cpp @@ -39,8 +39,7 @@ const std::string INVALID_PROPERTY; // Empty string for invalid calls GestureDetector::GestureDetector(Gesture::Type type) : mType(type), - mGestureEventProcessor(ThreadLocalStorage::Get().GetGestureEventProcessor()), - mSlotDelegate(this) + mGestureEventProcessor(ThreadLocalStorage::Get().GetGestureEventProcessor()) { } @@ -50,8 +49,9 @@ GestureDetector::~GestureDetector() { for ( GestureDetectorActorContainer::iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter ) { - (*iter)->RemoveObserver( *this ); - (*iter)->TouchedSignal().Disconnect( mSlotDelegate, &GestureDetector::OnTouchEvent ); + Actor* actor( *iter ); + actor->RemoveObserver( *this ); + actor->RemoveGestureDetector( *this ); } mAttachedActors.clear(); @@ -79,8 +79,8 @@ void GestureDetector::Attach(Actor& actor) // We need to observe the actor's destruction actor.AddObserver(*this); - // Dummy connection to touch event - actor.TouchedSignal().Connect( mSlotDelegate, &GestureDetector::OnTouchEvent ); + // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm) + actor.AddGestureDetector( *this ); // Notification for derived classes OnActorAttach(actor); @@ -98,10 +98,10 @@ void GestureDetector::Detach(Actor& actor) // We no longer need to observe the actor's destruction actor.RemoveObserver(*this); - mAttachedActors.erase(match); + // Remove detector from actor (so it is set to no longer requiring this gesture when going through the hit-test algorithm) + actor.RemoveGestureDetector( *this ); - // Disconnect connection to touch event - actor.TouchedSignal().Disconnect( mSlotDelegate, &PanGestureDetector::OnTouchEvent ); + mAttachedActors.erase(match); // Notification for derived classes OnActorDetach(actor); @@ -131,6 +131,9 @@ void GestureDetector::DetachAll() // We no longer need to observe the actor's destruction actor->RemoveObserver(*this); + // Remove detector from actor (so it is set to no longer requiring this gesture when going through the hit-test algorithm) + actor->RemoveGestureDetector( *this ); + // Notification for derived classes OnActorDetach(*actor); } @@ -182,11 +185,6 @@ void GestureDetector::ProxyDestroyed(ProxyObject& proxy) } } -bool GestureDetector::OnTouchEvent(Dali::Actor actor, const TouchEvent& event) -{ - return false; -} - bool GestureDetector::IsSceneObjectRemovable() const { return false; diff --git a/dali/internal/event/events/gesture-detector-impl.h b/dali/internal/event/events/gesture-detector-impl.h index f827e40..829b102 100644 --- a/dali/internal/event/events/gesture-detector-impl.h +++ b/dali/internal/event/events/gesture-detector-impl.h @@ -159,15 +159,6 @@ private: */ virtual void OnActorDestroyed(Object& object) = 0; - /** - * Dummy touch event handler. We do not need to know when touch happens on our actor. We just - * need to connect a function so that our attached actor is checked during our hit testing. - * @param[in] actor The hit actor (or one of its parents). - * @param[in] event The touch event. - * @return false always as we do not process the event. - */ - bool OnTouchEvent(Dali::Actor actor, const TouchEvent& event); - private: // Default property extensions from ProxyObject /** @@ -255,10 +246,6 @@ protected: Gesture::Type mType; ///< The gesture detector will detect this type of gesture. GestureDetectorActorContainer mAttachedActors; ///< Proxy::Observer is used to provide weak-pointer behaviour GestureEventProcessor& mGestureEventProcessor; ///< A reference to the gesture event processor. - -private: - - SlotDelegate< GestureDetector > mSlotDelegate; }; } // namespace Internal diff --git a/dali/internal/event/events/gesture-processor.cpp b/dali/internal/event/events/gesture-processor.cpp index f08ef86..42c4c7e 100644 --- a/dali/internal/event/events/gesture-processor.cpp +++ b/dali/internal/event/events/gesture-processor.cpp @@ -29,9 +29,41 @@ namespace Dali namespace Internal { -GestureProcessor::GestureProcessor() -: mCurrentGesturedActor( NULL ), - mGesturedActorDisconnected(false) +namespace +{ + +/** + * Functor to check whether an actor requires a particular gesture or not + */ +struct GestureHitTestCheck : public HitTestAlgorithm::HitTestInterface +{ + GestureHitTestCheck( Gesture::Type type ) + : mType( type ) + { + } + + virtual bool IsActorHittable( Actor* actor ) + { + return actor->IsGestureRequred( mType ) && // Does the Application or derived actor type require the gesture? + actor->IsHittable(); // Is actor sensitive, visible and on the scene? + } + + virtual bool DescendActorHierarchy( Actor* actor ) + { + 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. + } + + Gesture::Type mType; +}; + +} // unnamed namespace + + +GestureProcessor::GestureProcessor( Gesture::Type type ) +: mType( type ), + mCurrentGesturedActor( NULL ), + mGesturedActorDisconnected( false ) { } @@ -131,21 +163,9 @@ bool GestureProcessor::HitTest( Vector2 screenCoordinates, HitTestAlgorithm::Results& hitTestResults) { - bool hit = false; - - HitTestAlgorithm::HitTest( stage, screenCoordinates, hitTestResults ); - if( hitTestResults.renderTask && hitTestResults.actor ) - { - if( ! GetImplementation( hitTestResults.renderTask ).IsSystemLevel() ) - { - hit = true; - } - else - { - DALI_LOG_ERROR( "Gesture not possible in SystemOverlay" ); - } - } - return hit; + GestureHitTestCheck hitCheck( mType ); + HitTestAlgorithm::HitTest( stage, screenCoordinates, hitTestResults, hitCheck ); + return hitTestResults.renderTask && hitTestResults.actor; } void GestureProcessor::SetActor( Dali::Actor actor ) diff --git a/dali/internal/event/events/gesture-processor.h b/dali/internal/event/events/gesture-processor.h index 9441542..ff6c525 100644 --- a/dali/internal/event/events/gesture-processor.h +++ b/dali/internal/event/events/gesture-processor.h @@ -40,7 +40,7 @@ protected: // Construction & Destruction /** * Protected constructor. Cannot create an instance of GestureProcessor */ - GestureProcessor(); + GestureProcessor( Gesture::Type type ); /** * Virtual protected destructor. @@ -200,8 +200,9 @@ private: private: // Data - Actor* mCurrentGesturedActor; ///< The current actor that has been gestured. - bool mGesturedActorDisconnected; ///< Indicates whether the gestured actor has been disconnected from the scene + Gesture::Type mType; ///< Type of GestureProcessor + Actor* mCurrentGesturedActor; ///< The current actor that has been gestured. + bool mGesturedActorDisconnected:1; ///< Indicates whether the gestured actor has been disconnected from the scene }; } // namespace Internal diff --git a/dali/internal/event/events/long-press-gesture-processor.cpp b/dali/internal/event/events/long-press-gesture-processor.cpp index 1a83a67..3aa0222 100644 --- a/dali/internal/event/events/long-press-gesture-processor.cpp +++ b/dali/internal/event/events/long-press-gesture-processor.cpp @@ -144,10 +144,9 @@ struct LongPressGestureProcessor::LongPressEventFunctor : public GestureProcesso LongPressGestureProcessor& processor; }; -LongPressGestureProcessor::LongPressGestureProcessor( - Stage& stage, - Integration::GestureManager& gestureManager) -: mStage( stage ), +LongPressGestureProcessor::LongPressGestureProcessor( Stage& stage, Integration::GestureManager& gestureManager) +: GestureProcessor( Gesture::LongPress ), + mStage( stage ), mGestureManager( gestureManager ), mGestureDetectors(), mCurrentEmitters(), @@ -184,7 +183,7 @@ void LongPressGestureProcessor::Process( const Integration::LongPressGestureEven if ( currentGesturedActor ) { HitTestAlgorithm::Results hitTestResults; - HitTestAlgorithm::HitTest( mStage, longPressEvent.point, hitTestResults ); + HitTest( mStage, longPressEvent.point, hitTestResults ); if ( hitTestResults.actor && ( currentGesturedActor == &GetImplementation( hitTestResults.actor ) ) ) { diff --git a/dali/internal/event/events/pan-gesture-processor.cpp b/dali/internal/event/events/pan-gesture-processor.cpp index dd8e6d5..84b37b3 100644 --- a/dali/internal/event/events/pan-gesture-processor.cpp +++ b/dali/internal/event/events/pan-gesture-processor.cpp @@ -212,7 +212,8 @@ struct PanGestureProcessor::PanEventFunctor : public GestureProcessor::Functor }; PanGestureProcessor::PanGestureProcessor( Stage& stage, Integration::GestureManager& gestureManager ) -: mStage( stage ), +: GestureProcessor( Gesture::Pan ), + mStage( stage ), mGestureManager( gestureManager ), mGestureDetectors(), mCurrentPanEmitters(), @@ -262,7 +263,7 @@ void PanGestureProcessor::Process( const Integration::PanGestureEvent& panEvent // it can be told when the gesture ends as well. HitTestAlgorithm::Results hitTestResults; - HitTestAlgorithm::HitTest( mStage, mPossiblePanPosition, hitTestResults ); // Hit test original possible position... + HitTest( mStage, mPossiblePanPosition, hitTestResults ); // Hit test original possible position... if ( hitTestResults.actor && ( GetCurrentGesturedActor() == &GetImplementation( hitTestResults.actor ) ) ) { diff --git a/dali/internal/event/events/pinch-gesture-processor.cpp b/dali/internal/event/events/pinch-gesture-processor.cpp index de3970e..7d99118 100644 --- a/dali/internal/event/events/pinch-gesture-processor.cpp +++ b/dali/internal/event/events/pinch-gesture-processor.cpp @@ -140,7 +140,8 @@ struct PinchGestureProcessor::PinchEventFunctor : public GestureProcessor::Funct }; PinchGestureProcessor::PinchGestureProcessor( Stage& stage, Integration::GestureManager& gestureManager ) -: mStage(stage), +: GestureProcessor( Gesture::Pinch ), + mStage(stage), mGestureManager(gestureManager), mGestureDetectors(), mCurrentPinchEmitters() diff --git a/dali/internal/event/events/tap-gesture-processor.cpp b/dali/internal/event/events/tap-gesture-processor.cpp index 77b83be..09639d9 100644 --- a/dali/internal/event/events/tap-gesture-processor.cpp +++ b/dali/internal/event/events/tap-gesture-processor.cpp @@ -105,7 +105,8 @@ struct TapGestureProcessor::TapEventFunctor : public GestureProcessor::Functor }; TapGestureProcessor::TapGestureProcessor( Stage& stage, Integration::GestureManager& gestureManager) -: mStage( stage ), +: GestureProcessor( Gesture::Tap ), + mStage( stage ), mGestureManager( gestureManager ), mGestureDetectors(), mMinTapsRequired( 1 ), @@ -141,7 +142,7 @@ void TapGestureProcessor::Process( const Integration::TapGestureEvent& tapEvent if ( GetCurrentGesturedActor() ) { HitTestAlgorithm::Results hitTestResults; - HitTestAlgorithm::HitTest( mStage, tapEvent.point, hitTestResults ); + HitTest( mStage, tapEvent.point, hitTestResults ); if ( hitTestResults.actor && ( GetCurrentGesturedActor() == &GetImplementation( hitTestResults.actor ) ) ) {