From 197334092bf0d0a91cd3b28db7d346e2a024cb64 Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Thu, 12 Dec 2019 17:54:50 +0000 Subject: [PATCH] Pan now possible without a touch down Before you had to be listening to pan gestures before the touch-down event arrives. Change-Id: Id9fa1164ab43c038ab407950a5b794ab4976241e --- .../src/dali/utc-Dali-PanGestureDetector.cpp | 132 ++++++++++++++++++++- .../events/pan-gesture/pan-gesture-processor.cpp | 43 +++---- .../events/pan-gesture/pan-gesture-recognizer.cpp | 2 +- 3 files changed, 151 insertions(+), 26 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp index 815bcdc..dc0a402 100644 --- a/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp @@ -1104,6 +1104,128 @@ int UtcDaliPanGestureSignalReceptionEnsureCorrectSignalling(void) END_TEST; } +int UtcDaliPanGestureSignalReceptionAttachActorAfterDown(void) +{ + // This test checks to ensure a pan is possible after attaching an actor after a down (possible) event + + 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(); + + // Gesture possible in actor's area (using long-press) + uint32_t time = 100; + TestStartLongPress( application, 10.0f, 20.0f, time ); + time += TestGetFrameInterval(); + + // Attach actor to detector + SignalData data; + GestureReceivedFunctor functor( data ); + PanGestureDetector detector = PanGestureDetector::New(); + detector.DetectedSignal().Connect( &application, functor ); + detector.Attach(actor); + + // Start a pan, initially it'll only be possible, we shouldn't receive it + TestMovePan( application, Vector2( 10.0f, 20.0f ), time ); + time += TestGetFrameInterval(); + DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION); + + // Now the pan truly starts, we should receive a signal + TestMovePan( application, Vector2( 26.0f, 20.0f ), time ); + time += TestGetFrameInterval(); + TestMovePan( application, Vector2( 32.0f, 32.0f ), time ); + time += TestGetFrameInterval(); + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + + // Finish the pan, we should still receive a signal + data.Reset(); + TestEndPan( application, Vector2( 32.0f, 32.0f ), time ); + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliPanGestureSignalReceptionAttachActorAfterDownAfterInitialPanToAnotherActor(void) +{ + // This test checks to ensure a pan is possible after attaching an actor after a down (possible) event even if another + // pan actor was there before (parent) + + TestApplication application; + + Actor parent = Actor::New(); + parent.SetSize(100.0f, 100.0f); + parent.SetAnchorPoint(AnchorPoint::TOP_LEFT); + Stage::GetCurrent().Add( parent ); + + Actor child = Actor::New(); + child.SetSize(100.0f, 100.0f); + child.SetAnchorPoint(AnchorPoint::CENTER); + child.SetParentOrigin(ParentOrigin::CENTER); + parent.Add( child ); + + // Create detector for parent and attach + SignalData parentData; + GestureReceivedFunctor parentFunctor( parentData ); + PanGestureDetector parentDetector = PanGestureDetector::New(); + parentDetector.DetectedSignal().Connect( &application, parentFunctor ); + parentDetector.Attach( parent ); + + // Create detector for child but do not attach + SignalData childData; + GestureReceivedFunctor childFunctor( childData ); + PanGestureDetector childDetector = PanGestureDetector::New(); + childDetector.DetectedSignal().Connect( &application, childFunctor ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Do a full pan in both actors' area, only the parent's functor should be called + uint32_t time = 100; + TestStartPan( application, Vector2( 10.0f, 20.0f ), Vector2( 26.0f, 20.0f ), time ); + DALI_TEST_EQUALS( parentData.functorCalled, true, TEST_LOCATION ); + DALI_TEST_EQUALS( childData.functorCalled, false, TEST_LOCATION ); + parentData.Reset(); + childData.Reset(); + TestEndPan( application, Vector2( 26.0f, 20.0f ), time ); + DALI_TEST_EQUALS( parentData.functorCalled, true, TEST_LOCATION ); + DALI_TEST_EQUALS( childData.functorCalled, false, TEST_LOCATION ); + parentData.Reset(); + childData.Reset(); + + // Gesture possible in both actors' area (using long-press), no functors called + TestStartLongPress( application, 10.0f, 20.0f, time ); + time += TestGetFrameInterval(); + DALI_TEST_EQUALS( parentData.functorCalled, false, TEST_LOCATION ); + DALI_TEST_EQUALS( childData.functorCalled, false, TEST_LOCATION ); + + // Attach the child as well now + childDetector.Attach( child ); + + // Now the pan truly starts, we should receive a signal for the child only + TestMovePan( application, Vector2( 26.0f, 20.0f ), time ); + time += TestGetFrameInterval(); + TestMovePan( application, Vector2( 32.0f, 32.0f ), time ); + time += TestGetFrameInterval(); + DALI_TEST_EQUALS( parentData.functorCalled, false, TEST_LOCATION ); + DALI_TEST_EQUALS( childData.functorCalled, true, TEST_LOCATION ); + parentData.Reset(); + childData.Reset(); + + // Finish the pan, again only the child should still receive a signal + TestEndPan( application, Vector2( 32.0f, 32.0f ), time ); + DALI_TEST_EQUALS( parentData.functorCalled, false, TEST_LOCATION ); + DALI_TEST_EQUALS( childData.functorCalled, true, TEST_LOCATION ); + + END_TEST; +} + int UtcDaliPanGestureSignalReceptionDifferentPossible(void) { TestApplication application; @@ -1125,7 +1247,6 @@ int UtcDaliPanGestureSignalReceptionDifferentPossible(void) detector.DetectedSignal().Connect( &application, functor ); // Gesture possible in actor's area. -// application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10)); uint32_t time = 100; TestStartLongPress( application, 10.0f, 20.0f, time ); time += TestGetFrameInterval(); @@ -1139,7 +1260,7 @@ int UtcDaliPanGestureSignalReceptionDifferentPossible(void) application.SendNotification(); application.Render(); - // Emit Started event, we should not receive the long press. + // Emit Started event, we should not receive the pan. TestStartPan( application, Vector2( 10.0f, 20.0f ), Vector2( 26.0f, 20.0f ), time ); TestEndPan( application, Vector2( 26.0f, 20.0f ), time ); time += TestGetFrameInterval(); @@ -1159,14 +1280,15 @@ int UtcDaliPanGestureSignalReceptionDifferentPossible(void) application.SendNotification(); application.Render(); - // Emit Started event, we should not receive the long press. + // Emit Started event, we should be receiving the pan now. TestStartPan( application, Vector2( 10.0f, 20.0f ), Vector2( 26.0f, 20.0f ), time ); TestEndPan( application, Vector2( 26.0f, 20.0f ), time ); time += TestGetFrameInterval(); - DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); - // Normal long press in actor's area for completeness. + // Normal pan in actor's area for completeness. + data.Reset(); TestStartPan( application, Vector2( 10.0f, 20.0f ), Vector2( 26.0f, 20.0f ), time ); TestEndPan( application, Vector2( 26.0f, 20.0f ), time ); DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); diff --git a/dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp b/dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp index 05589ef..51bef8d 100644 --- a/dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp +++ b/dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp @@ -167,7 +167,6 @@ void PanGestureProcessor::Process( Scene& scene, const PanGestureEvent& panEvent SetActor( &GetImplementation( hitTestResults.actor ) ); mPossiblePanPosition = panEvent.currentPosition; } - break; } @@ -176,29 +175,33 @@ void PanGestureProcessor::Process( Scene& scene, const PanGestureEvent& panEvent // Requires a core update mNeedsUpdate = true; - if ( GetCurrentGesturedActor() ) - { - // The pan gesture should only be sent to the gesture detector which first received it so that - // it can be told when the gesture ends as well. - - HitTestAlgorithm::Results hitTestResults; - HitTest( scene, mPossiblePanPosition, hitTestResults ); // Hit test original possible position... + // The pan gesture should only be sent to the gesture detector which first received it so that + // it can be told when the gesture ends as well. - if ( hitTestResults.actor && ( GetCurrentGesturedActor() == &GetImplementation( hitTestResults.actor ) ) ) - { - // Record the current render-task for Screen->Actor coordinate conversions - mCurrentRenderTask = hitTestResults.renderTask; + HitTestAlgorithm::Results hitTestResults; + HitTest( scene, panEvent.previousPosition, hitTestResults ); // Hit Test previous position - // Set mCurrentPanEvent to use inside overridden methods called in ProcessAndEmit() - mCurrentPanEvent = &panEvent; - ProcessAndEmit( hitTestResults ); - mCurrentPanEvent = nullptr; - } - else + if ( hitTestResults.actor ) + { + // If the current hit actor is different from the one we touched down on then set accordingly & update initial pan position + if( &GetImplementation( hitTestResults.actor ) != GetCurrentGesturedActor() ) { - ResetActor(); - mCurrentPanEmitters.clear(); + mPossiblePanPosition = panEvent.previousPosition; + SetActor( &GetImplementation( hitTestResults.actor ) ); } + + // Record the current render-task for Screen->Actor coordinate conversions + mCurrentRenderTask = hitTestResults.renderTask; + + // Set mCurrentPanEvent to use inside overridden methods called in ProcessAndEmit() + mCurrentPanEvent = &panEvent; + ProcessAndEmit( hitTestResults ); + mCurrentPanEvent = nullptr; + } + else + { + ResetActor(); + mCurrentPanEmitters.clear(); } break; } diff --git a/dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp b/dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp index 0256821..0b56574 100644 --- a/dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp +++ b/dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp @@ -99,7 +99,7 @@ void PanGestureRecognizer::SendEvent(const Integration::TouchEvent& event) { case Clear: { - if ( ( primaryPointState == PointState::DOWN ) || ( primaryPointState == PointState::STATIONARY ) ) + if ( ( primaryPointState == PointState::DOWN ) || ( primaryPointState == PointState::STATIONARY ) || ( primaryPointState == PointState::MOTION )) { mPrimaryTouchDownLocation = event.points[0].GetScreenPosition(); mPrimaryTouchDownTime = event.time; -- 2.7.4