X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fevents%2Fgesture-processor.cpp;h=c294c54682a4c1b98fafadef2391b2741ab57726;hb=bf075bb5a7cbe9701f6504c3c8fc056561c43479;hp=f08ef86b0bdb556ad360e5cecc906c8d57b65959;hpb=10e32f909ba912789532bf4f207c239d2614c7c4;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/events/gesture-processor.cpp b/dali/internal/event/events/gesture-processor.cpp index f08ef86..c294c54 100644 --- a/dali/internal/event/events/gesture-processor.cpp +++ b/dali/internal/event/events/gesture-processor.cpp @@ -1,18 +1,19 @@ -// -// 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. -// +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + */ // CLASS HEADER #include @@ -20,8 +21,11 @@ // INTERNAL INCLUDES #include #include -#include +#include +#include #include +#include +#include namespace Dali { @@ -29,132 +33,179 @@ 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( DevelGesture::Type type ) + : mType( type ) + { + } + + GestureHitTestCheck( Gesture::Type type ) + : GestureHitTestCheck( static_cast< DevelGesture::Type >( 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. + } + + virtual bool DoesLayerConsumeHit( Layer* layer ) + { + return layer->IsTouchConsumed(); + } + + DevelGesture::Type mType; +}; + +} // unnamed namespace + + +GestureProcessor::GestureProcessor( DevelGesture::Type type ) +: mGestureRecognizer(), + mNeedsUpdate( false ), + mType( type ), + mCurrentGesturedActor( nullptr ), + mGesturedActorDisconnected( false ) { } +GestureProcessor::GestureProcessor( Gesture::Type type ) +: GestureProcessor( static_cast< DevelGesture::Type >( type ) ) +{ +} + + GestureProcessor::~GestureProcessor() { ResetActor(); } -void GestureProcessor::GetGesturedActor( Dali::Actor& actor, const GestureDetectorContainer& connectedDetectors, std::vector& gestureDetectors, Functor& functor ) +void GestureProcessor::ProcessTouch( Scene& scene, const Integration::TouchEvent& event ) { - while ( actor ) + if( mGestureRecognizer ) { - Actor* actorImpl( &GetImplementation(actor) ); + mGestureRecognizer->SendEvent(scene, event); + } +} - // Check if our hit actor or any of its parents are attached to any registered detector. - // Find all detectors that have the actor attached. - for ( GestureDetectorContainer::const_iterator iter = connectedDetectors.begin(), endIter = connectedDetectors.end(); iter != endIter; ++iter ) +void GestureProcessor::GetGesturedActor( Actor*& actor, GestureDetectorContainer& gestureDetectors ) +{ + while ( actor ) + { + // We may be checking a parent so ensure the parent requires this gesture (and do not unintentionally create the gesture data for the parent) + if ( actor->IsGestureRequred( mType ) ) { - GestureDetector* current(*iter); - - // Check whether the actor is attached to the gesture detector and then call the functor to - // check whether the gesture detector satisfies the current gesture's parameters. - if ( current->IsAttached( *actorImpl ) && functor( current, actorImpl ) ) + // Retrieve the actor's detectors and check if they satisfy current gesture + const GestureDetectorContainer& connectedDetectors( actor->GetGestureData().GetGestureDetectorContainer( mType ) ); + const GestureDetectorContainer::const_iterator endIter( connectedDetectors.end() ); + for ( GestureDetectorContainer::const_iterator iter = connectedDetectors.begin(); iter != endIter; ++iter ) { - gestureDetectors.push_back(current); + GestureDetector* current(*iter); + + // Check deriving class for whether the current gesture satisfies the gesture detector's parameters. + if ( CheckGestureDetector( current, actor ) ) + { + gestureDetectors.push_back(current); + } } - } - // The hit actor or one of the parents is a gestured actor, break out. - if ( !gestureDetectors.empty() ) - { - break; + // The hit actor or one of the parents is a gestured actor, break out. + if ( !gestureDetectors.empty() ) + { + break; + } } // No match, we should now check the hit actor's parent. - actor = actor.GetParent(); + actor = actor->GetParent(); } } -void GestureProcessor::ProcessAndEmit( const HitTestAlgorithm::Results& hitTestResults, const GestureDetectorContainer& connectedDetectors, Functor& functor ) +void GestureProcessor::ProcessAndEmit( HitTestAlgorithm::Results& hitTestResults ) { - Dali::Actor actor( hitTestResults.actor ); - - while ( actor ) + if ( hitTestResults.actor ) { - std::vector gestureDetectors; + Actor* hitTestActor( &GetImplementation( hitTestResults.actor ) ); + Actor* actor( hitTestActor ); - GetGesturedActor( actor, connectedDetectors, gestureDetectors, functor ); - - if ( actor && !gestureDetectors.empty() ) + while ( actor ) { - // We have a match but check if the hit point is within the gestured actor's bounds. - // If it is not then continue up the actor hierarchy. + GestureDetectorContainer gestureDetectors; + GetGesturedActor( actor, gestureDetectors ); - if ( actor == hitTestResults.actor ) - { - // Our gesture detector's attached actor WAS the hit actor so we can call the emitting functor. - functor( actor, gestureDetectors, hitTestResults.actorCoordinates ); - break; // We have found AND emitted a signal on the gestured actor, break out. - } - else + if ( actor && !gestureDetectors.empty() ) { - if ( GetImplementation(actor).IsHittable() ) - { - const Vector3 size( actor.GetCurrentSize() ); + // We have a match but check if the hit point is within the gestured actor's bounds. + // If it is not then continue up the actor hierarchy. - if ( ( size.x > 0.0f ) && ( size.y > 0.0f ) ) + if ( actor == hitTestActor ) + { + // Our gesture detector's attached actor WAS the hit actor so we can can emit the signal. + EmitGestureSignal( actor, gestureDetectors, hitTestResults.actorCoordinates ); + break; // We have found AND emitted a signal on the gestured actor, break out. + } + else + { + if ( actor->IsHittable() ) { - // Ensure tap is within the actor's area - Actor& actorImpl = GetImplementation(actor); - if ( actorImpl.RaySphereTest( hitTestResults.rayOrigin, hitTestResults.rayDirection ) ) // Quick check + const Vector3 size( actor->GetCurrentSize() ); + + if ( ( size.x > 0.0f ) && ( size.y > 0.0f ) ) { - Vector4 hitPointLocal; - float distance( 0.0f ); - if( actorImpl.RayActorTest( hitTestResults.rayOrigin, hitTestResults.rayDirection, hitPointLocal, distance ) ) + // Ensure tap is within the actor's area + if ( actor->RaySphereTest( hitTestResults.rayOrigin, hitTestResults.rayDirection ) ) // Quick check { - // One of the hit actor's parents was the gestured actor so call the emitting functor. - functor( actor, gestureDetectors, Vector2( hitPointLocal.x, hitPointLocal.y ) ); - break; // We have found AND emitted a signal on the gestured actor, break out. + Vector2 hitPointLocal; + float distance( 0.0f ); + if( actor->RayActorTest( hitTestResults.rayOrigin, hitTestResults.rayDirection, hitPointLocal, distance ) ) + { + // One of the parents was the gestured actor so we can emit the signal for that actor. + EmitGestureSignal( actor, gestureDetectors, hitPointLocal ); + break; // We have found AND emitted a signal on the gestured actor, break out. + } } } } } } - } - // Continue up hierarchy to see if any of the parents require this gesture. - if ( actor ) - { - actor = actor.GetParent(); + // Continue up hierarchy to see if any of the parents require this gesture. + if ( actor ) + { + actor = actor->GetParent(); + } } } } -bool GestureProcessor::HitTest( - Stage& stage, - Vector2 screenCoordinates, - HitTestAlgorithm::Results& hitTestResults) +bool GestureProcessor::HitTest( Scene& scene, 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( scene.GetSize(), scene.GetRenderTaskList(), scene.GetLayerList(), screenCoordinates, hitTestResults, hitCheck ); + return hitTestResults.renderTask && hitTestResults.actor; } -void GestureProcessor::SetActor( Dali::Actor actor ) +void GestureProcessor::SetActor( Actor* actor ) { if ( actor && actor != mCurrentGesturedActor ) { ResetActor(); - mCurrentGesturedActor = &GetImplementation( actor ); + mCurrentGesturedActor = actor; mCurrentGesturedActor->AddObserver( *this ); } mGesturedActorDisconnected = false; @@ -165,37 +216,37 @@ void GestureProcessor::ResetActor() if ( mCurrentGesturedActor ) { mCurrentGesturedActor->RemoveObserver( *this ); - mCurrentGesturedActor = NULL; + mCurrentGesturedActor = nullptr; mGesturedActorDisconnected = false; } } Actor* GestureProcessor::GetCurrentGesturedActor() { - return mGesturedActorDisconnected ? NULL : mCurrentGesturedActor; + return mGesturedActorDisconnected ? nullptr : mCurrentGesturedActor; } -void GestureProcessor::SceneObjectRemoved(ProxyObject& proxy) +void GestureProcessor::SceneObjectRemoved(Object& object) { - if ( mCurrentGesturedActor == &proxy && + if ( mCurrentGesturedActor == &object && !mGesturedActorDisconnected ) { // Inform deriving classes. OnGesturedActorStageDisconnection(); - // do not call proxy.RemoveObserver here, proxy is currently iterating through observers... you wouldnt want to upset proxy now would you? + // do not call object.RemoveObserver here, object is currently iterating through observers... you wouldnt want to upset object now would you? mGesturedActorDisconnected = true; } } -void GestureProcessor::ProxyDestroyed(ProxyObject& proxy) +void GestureProcessor::ObjectDestroyed(Object& object) { - if ( mCurrentGesturedActor == &proxy ) + if ( mCurrentGesturedActor == &object ) { // Inform deriving classes. OnGesturedActorStageDisconnection(); - mCurrentGesturedActor = NULL; + mCurrentGesturedActor = nullptr; } }