#endif
// INTERNAL INCLUDES
-#include <dali/public-api/actors/renderable-actor.h>
#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/signals/callback.h>
#include <dali/integration-api/debug.h>
#include <dali/integration-api/events/touch-event-integ.h>
#include <dali/internal/event/actors/actor-impl.h>
#include <dali/internal/event/actors/layer-impl.h>
#include <dali/internal/event/common/stage-impl.h>
#include <dali/internal/event/events/hit-test-algorithm-impl.h>
+#include <dali/internal/event/events/multi-point-event-util.h>
#include <dali/internal/event/render-tasks/render-task-impl.h>
namespace Dali
namespace
{
-bool IsActuallySensitive( Actor* actor );
-
#if defined(DEBUG_ENABLED)
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TOUCH_PROCESSOR" );
"Interrupted",
};
-static const Debug::LogLevel HIERARCHY_DEBUG_LOG_LEVEL( Debug::Verbose );
-
-static bool HIERARCHY_GEOMETRY( false );
-static bool HIERARCHY_SENSITIVITY( false );
-static bool HIERARCHY_TOUCH_REQUIRED( false );
-static bool HIERARCHY_HITTABLE( false );
-
-/**
- * Prints out all the children of the given actor when debug is enabled.
- *
- * @param[in] actor The actor whose children to print.
- * @param[in] level The number of " | " to put in front of the children.
- */
-void PrintChildren( Dali::Actor actor, int level )
-{
- std::ostringstream output;
-
- for ( int t = 0; t < level; ++t )
- {
- output << " | ";
- }
-
- output << actor.GetName() << "(" << actor.GetTypeName() << ", " << actor.GetObjectPtr() << ")";
-
- if ( HIERARCHY_GEOMETRY )
- {
- output << " Pos: " << actor.GetCurrentWorldPosition() << " Size: " << actor.GetCurrentSize() << " Scale: " << actor.GetCurrentWorldScale();
- }
-
- if ( HIERARCHY_SENSITIVITY )
- {
- output << " Sensitivity: " << ( IsActuallySensitive( &GetImplementation( actor ) ) ? "True " : "False " );
- }
-
- if ( HIERARCHY_TOUCH_REQUIRED )
- {
- output << " TouchRequired: " << ( GetImplementation(actor).GetTouchRequired() ? "True " : "False " );
- }
-
- if ( HIERARCHY_HITTABLE )
- {
- output << " Hittable: " << ( GetImplementation(actor).IsHittable() ? "True " : "False " );
- }
-
- output << std::endl;
-
- DALI_LOG_INFO( gLogFilter, HIERARCHY_DEBUG_LOG_LEVEL, output.str().c_str() );
-
- ++level;
- unsigned int numChildren=actor.GetChildCount();
- for ( unsigned int i=0; i<numChildren; ++i )
- {
- PrintChildren( actor.GetChildAt(i), level );
- }
- --level;
-}
-
-/**
- * Prints the entire hierarchy of the scene.
- */
-void PrintHierarchy()
-{
- if ( gLogFilter->IsEnabledFor( HIERARCHY_DEBUG_LOG_LEVEL ) )
- {
- PrintChildren( Dali::Stage().GetCurrent().GetRootLayer(), 0 );
- }
-}
-
-#define PRINT_HIERARCHY PrintHierarchy()
-
-#else // defined(DEBUG_ENABLED)
-
-#define PRINT_HIERARCHY
-
#endif // defined(DEBUG_ENABLED)
/**
Dali::Actor EmitTouchSignals( Actor* actor, RenderTask& renderTask, const TouchEvent& originalEvent, TouchPoint::State state )
{
TouchEvent touchEvent( originalEvent );
- TouchPoint& primaryPoint = touchEvent.points[0];
-
- actor->ScreenToLocal( renderTask, primaryPoint.local.x, primaryPoint.local.y, primaryPoint.screen.x, primaryPoint.screen.y );
- primaryPoint.hitActor = actor;
- primaryPoint.state = state;
+ DALI_ASSERT_DEBUG( NULL != actor && "NULL actor pointer" );
+ if( actor )
+ {
+ TouchPoint& primaryPoint = touchEvent.points[0];
- return EmitTouchSignals( Dali::Actor(actor), touchEvent );
-}
+ actor->ScreenToLocal( renderTask, primaryPoint.local.x, primaryPoint.local.y, primaryPoint.screen.x, primaryPoint.screen.y );
-/**
- * In the hit test algorithm above we do not descend actor tree if it is insensitive, so here, we
- * should also check if any of the actor's parents has become insensitive since we last processed
- * it.
- */
-bool IsActuallySensitive( Actor* actor )
-{
- bool sensitive = true;
-
- while ( actor && sensitive )
- {
- sensitive = actor->IsSensitive();
- actor = actor->GetParent();
+ primaryPoint.hitActor = Dali::Actor(actor);
+ primaryPoint.state = state;
}
- return sensitive;
+ return EmitTouchSignals( Dali::Actor(actor), touchEvent );
}
} // unnamed namespace
TouchEventProcessor::TouchEventProcessor( Stage& stage )
: mStage( stage ),
- mLastPrimaryHitActor(),
+ mLastPrimaryHitActor( MakeCallback( this, &TouchEventProcessor::OnObservedActorDisconnected ) ),
mLastConsumedActor(),
mTouchDownConsumedActor(),
mLastRenderTask()
Stage& stage = mStage;
- PRINT_HIERARCHY;
+ PRINT_HIERARCHY(gLogFilter);
// Copy so we can add the results of a hit-test.
TouchEvent touchEvent( event.time );
mTouchDownConsumedActor.SetActor( NULL );
mLastRenderTask.Reset();
- touchEvent.points[0].hitActor = NULL;
+ touchEvent.points[0].hitActor.Reset();
mStage.EmitTouchedSignal( touchEvent );
return; // No need for hit testing
}
}
-TouchEventProcessor::ActorObserver::ActorObserver()
-: mActor ( NULL ),
- mActorDisconnected(false)
+void TouchEventProcessor::OnObservedActorDisconnected( Actor* actor )
{
- DALI_LOG_TRACE_METHOD( gLogFilter );
-}
-
-TouchEventProcessor::ActorObserver::~ActorObserver()
-{
- DALI_LOG_TRACE_METHOD( gLogFilter );
- SetActor( NULL );
-}
-
-Actor* TouchEventProcessor::ActorObserver::GetActor()
-{
- return mActorDisconnected ? NULL : mActor;
-}
-
-void TouchEventProcessor::ActorObserver::SetActor( Actor* actor )
-{
- DALI_LOG_TRACE_METHOD( gLogFilter );
-
- if ( mActor != actor )
+ if ( actor == mLastPrimaryHitActor.GetActor() )
{
- ResetActor();
+ Dali::Actor handle( actor );
+ TouchEvent touchEvent( 0 );
+ touchEvent.points.push_back( TouchPoint( 0, TouchPoint::Interrupted, 0.0f, 0.0f ) );
+ touchEvent.points[0].hitActor = handle;
- mActor = actor;
+ Dali::Actor eventConsumer = EmitTouchSignals( handle, touchEvent );
- if ( mActor )
+ if ( mLastConsumedActor.GetActor() != eventConsumer )
{
- mActor->AddObserver( *this );
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Start Observing: %p\n", mActor);
+ EmitTouchSignals( Dali::Actor( mLastConsumedActor.GetActor() ), touchEvent );
}
- }
-
- // Make sure this flag is unset (as we may have been disconnected if it's the same actor)
- mActorDisconnected = false;
-}
-void TouchEventProcessor::ActorObserver::ResetActor()
-{
- if ( mActor )
- {
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Stop Observing: %p\n", mActor);
- mActor->RemoveObserver( *this );
- mActor = NULL;
- mActorDisconnected = false;
- }
-}
-
-void TouchEventProcessor::ActorObserver::SceneObjectRemoved( ProxyObject& proxy )
-{
- DALI_LOG_TRACE_METHOD( gLogFilter );
+ // Do not set mLastPrimaryHitActor to NULL we may be iterating through its observers
- if ( mActor == &proxy )
- {
- // do not call proxy.RemoveObserver here, proxy is currently iterating through observers... you wouldnt want to upset proxy now would you?
- mActorDisconnected = true;
- }
-}
-
-void TouchEventProcessor::ActorObserver::ProxyDestroyed(ProxyObject& proxy)
-{
- DALI_LOG_TRACE_METHOD( gLogFilter );
-
- if ( mActor == &proxy )
- {
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Stop Observing: %p\n", mActor);
- mActor = NULL;
+ mLastConsumedActor.SetActor( NULL );
+ mLastRenderTask.Reset();
}
}