Added class to replace TouchEvent 08/70808/12
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 19 May 2016 17:18:33 +0000 (18:18 +0100)
committerDavid Steele <david.steele@samsung.com>
Thu, 2 Jun 2016 13:56:27 +0000 (14:56 +0100)
Fixes following review:

Removed Internal::TouchData::GetPoint()
Cleaned up signal sending from TouchEventProcessor
Changed new Actor::TouchSignal to pass TouchData handle as const ref.
Changed new Stage::TouchedSignal to pass TouchData handle as const ref.
Changed API of TouchData to return by value where appropriate and removed
all asserts.
Changed API of TouchData to use size_t for point index and point count.

Added test cases for touch processing using touch data ( a copy and paste
of the existing test cases, plus a negative test case for the out of bounds
check in the public API for TouchData )

Change-Id: I8a58775f7a70a3bed8514439c627f261ac4f5807

21 files changed:
automated-tests/src/dali/CMakeLists.txt
automated-tests/src/dali/utc-Dali-TouchDataProcessing.cpp [new file with mode: 0644]
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/common/stage-impl.cpp
dali/internal/event/common/stage-impl.h
dali/internal/event/events/touch-data-impl.cpp [new file with mode: 0644]
dali/internal/event/events/touch-data-impl.h [new file with mode: 0644]
dali/internal/event/events/touch-event-processor.cpp
dali/internal/file.list
dali/public-api/actors/actor.cpp
dali/public-api/actors/actor.h
dali/public-api/actors/custom-actor-impl.h
dali/public-api/common/stage.cpp
dali/public-api/common/stage.h
dali/public-api/dali-core.h
dali/public-api/events/point-state.h [new file with mode: 0644]
dali/public-api/events/touch-data.cpp [new file with mode: 0644]
dali/public-api/events/touch-data.h [new file with mode: 0644]
dali/public-api/events/touch-event.h
dali/public-api/file.list

index 112ef14..f5e73a5 100644 (file)
@@ -66,6 +66,7 @@ SET(TC_SOURCES
         utc-Dali-TapGestureDetector.cpp
         utc-Dali-TouchEventCombiner.cpp
         utc-Dali-TouchProcessing.cpp
+        utc-Dali-TouchDataProcessing.cpp
         utc-Dali-TypeRegistry.cpp
         utc-Dali-Uint16Pair.cpp
         utc-Dali-Vector.cpp
diff --git a/automated-tests/src/dali/utc-Dali-TouchDataProcessing.cpp b/automated-tests/src/dali/utc-Dali-TouchDataProcessing.cpp
new file mode 100644 (file)
index 0000000..d92bf87
--- /dev/null
@@ -0,0 +1,1708 @@
+/*
+ * Copyright (c) 2016 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.
+ *
+ */
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/system-overlay.h>
+#include <dali-test-suite-utils.h>
+
+using namespace Dali;
+
+void utc_dali_touch_data_processing_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_touch_data_processing_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+struct TestPoint
+{
+  int32_t deviceId;
+  PointState::Type state;
+  Actor hitActor;
+  Vector2 local;
+  Vector2 screen;
+
+  TestPoint()
+  : deviceId(-1), state(PointState::FINISHED)
+  {
+  }
+  static const TestPoint ZERO;
+};
+
+const TestPoint TestPoint::ZERO;
+
+
+// Stores data that is populated in the callback and will be read by the TET cases
+struct SignalData
+{
+  SignalData()
+  : functorCalled( false ),
+    touchData(),
+    touchedActor()
+  {
+  }
+
+  struct TestTouchData
+  {
+    unsigned long time;
+    std::vector<TestPoint> points;
+
+    const TestPoint& GetPoint(size_t i)
+    {
+      if( i < points.size() )
+      {
+        return points[i];
+      }
+      return TestPoint::ZERO;
+    }
+    size_t GetPointCount()
+    {
+      return points.size();
+    }
+  };
+
+  void Reset()
+  {
+    functorCalled = false;
+
+    touchData.time = 0u;
+    touchData.points.clear();
+
+    touchedActor.Reset();
+  }
+
+  bool functorCalled;
+  TestTouchData touchData;
+  Actor touchedActor;
+};
+
+// Functor that sets the data when called
+struct TouchDataFunctor
+{
+  /**
+   * Constructor.
+   * @param[in]  data         Reference to the data to store callback information.
+   * @param[in]  returnValue  What the functor should return.
+   */
+  TouchDataFunctor( SignalData& data, bool returnValue = true )
+  : signalData( data ),
+    returnValue( returnValue )
+  {
+  }
+
+  bool operator()( Actor actor, const TouchData& touchData )
+  {
+    signalData.functorCalled = true;
+    signalData.touchedActor = actor;
+
+    signalData.touchData.time = touchData.GetTime();
+    signalData.touchData.points.clear();
+
+    for( size_t i=0; i<touchData.GetPointCount(); ++i )
+    {
+      TestPoint p;
+      p.deviceId = touchData.GetDeviceId(i);
+      p.state = touchData.GetState(i);
+      p.hitActor = touchData.GetHitActor(i);
+      p.local = touchData.GetLocalPosition(i);
+      p.screen = touchData.GetScreenPosition(i);
+      signalData.touchData.points.push_back(p);
+    }
+
+    return returnValue;
+  }
+
+  SignalData& signalData;
+  bool returnValue;
+};
+
+// Functor that removes the actor when called.
+struct RemoveActorFunctor : public TouchDataFunctor
+{
+  /**
+   * Constructor.
+   * @param[in]  data         Reference to the data to store callback information.
+   * @param[in]  returnValue  What the functor should return.
+   */
+  RemoveActorFunctor( SignalData& data, bool returnValue = true )
+  : TouchDataFunctor( data, returnValue )
+  {
+  }
+
+  bool operator()( Actor actor, const TouchData& touchData )
+  {
+    Actor parent( actor.GetParent() );
+    if ( parent )
+    {
+      parent.Remove( actor );
+    }
+
+    return TouchDataFunctor::operator()( actor, touchData );
+  }
+};
+
+struct OutOfBoundsData
+{
+  TestPoint point;
+  bool functorCalled;
+
+  OutOfBoundsData()
+  :functorCalled(false)
+  {
+  }
+};
+
+// Functor that reads out of bounds data when called
+struct OutOfBoundsFunctor
+{
+  /**
+   * Constructor.
+   * @param[in]  data         Reference to the data to store callback information.
+   * @param[in]  returnValue  What the functor should return.
+   */
+  OutOfBoundsFunctor( OutOfBoundsData& data, bool returnValue = true )
+  : outOfBoundsData ( data ),
+    returnValue( returnValue )
+  {
+  }
+
+  bool operator()( Actor actor, const TouchData& touchData )
+  {
+    outOfBoundsData.functorCalled = true;
+    size_t count = touchData.GetPointCount();
+
+    // Read out of bounds data
+    outOfBoundsData.point.deviceId = touchData.GetDeviceId(count+1);
+    outOfBoundsData.point.state = touchData.GetState(count+1);
+    outOfBoundsData.point.hitActor = touchData.GetHitActor(count+1);
+    outOfBoundsData.point.local = touchData.GetLocalPosition(count+1);
+    outOfBoundsData.point.screen = touchData.GetScreenPosition(count+1);
+
+    return returnValue;
+  }
+
+  OutOfBoundsData& outOfBoundsData;
+  bool returnValue;
+};
+
+Integration::TouchEvent GenerateSingleTouch( TouchPoint::State state, Vector2 screenPosition )
+{
+  Integration::TouchEvent touchEvent;
+  touchEvent.points.push_back( TouchPoint ( 0, state, screenPosition.x, screenPosition.y ) );
+  return touchEvent;
+}
+
+} // anon namespace
+
+///////////////////////////////////////////////////////////////////////////////
+
+int UtcDaliTouchDataNormalProcessing(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;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  Vector2 screenCoordinates( 10.0f, 10.0f );
+  Vector2 localCoordinates;
+  actor.ScreenToLocal( localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  const TestPoint *point1 = &data.touchData.GetPoint(0);
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, data.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, point1->state, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, point1->screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( localCoordinates, point1->local, 0.1f, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a motion signal
+  screenCoordinates.x = screenCoordinates.y = 11.0f;
+  actor.ScreenToLocal( localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, screenCoordinates ) );
+  const TestPoint *point2 = &data.touchData.GetPoint(0);
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, data.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::MOTION, point2->state, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, point2->screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( localCoordinates, point2->local, 0.1f, TEST_LOCATION );
+  data.Reset();
+
+  // Emit an up signal
+  screenCoordinates.x = screenCoordinates.y = 12.0f;
+  actor.ScreenToLocal( localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Up, screenCoordinates ) );
+  const TestPoint *point3 = &data.touchData.GetPoint(0);
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, data.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::UP, point3->state, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, point3->screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( localCoordinates, point3->local, 0.1f, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a down signal where the actor is not present
+  screenCoordinates.x = screenCoordinates.y = 200.0f;
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  END_TEST;
+}
+
+
+int UtcDaliTouchDataAPINegative(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
+  OutOfBoundsData data;
+  OutOfBoundsFunctor functor( data, true );
+  actor.TouchSignal().Connect( &application, functor );
+
+  Vector2 screenCoordinates( 10.0f, 10.0f );
+  Vector2 localCoordinates;
+  actor.ScreenToLocal( localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( -1, data.point.deviceId, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::FINISHED, data.point.state, TEST_LOCATION );
+  DALI_TEST_EQUALS( Vector2::ZERO, data.point.screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( Vector2::ZERO, data.point.local, 0.1f, TEST_LOCATION );
+  DALI_TEST_CHECK( ! data.point.hitActor );
+
+  END_TEST;
+}
+
+
+int UtcDaliTouchDataOutsideCameraNearFarPlanes(void)
+{
+  TestApplication application;
+
+  Stage stage = Stage::GetCurrent();
+  Vector2 stageSize = stage.GetSize();
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::CENTER);
+  actor.SetParentOrigin(ParentOrigin::CENTER);
+  stage.Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Get the camera's near and far planes
+  RenderTaskList taskList = stage.GetRenderTaskList();
+  Dali::RenderTask task = taskList.GetTask(0);
+  CameraActor camera = task.GetCameraActor();
+  float nearPlane = camera.GetNearClippingPlane();
+  float farPlane = camera.GetFarClippingPlane();
+
+  // Calculate the current distance of the actor from the camera
+  float tanHalfFov = tanf(camera.GetFieldOfView() * 0.5f);
+  float distance = (stageSize.y * 0.5f) / tanHalfFov;
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  Vector2 screenCoordinates( stageSize.x * 0.5f, stageSize.y * 0.5f );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a down signal where actor is just at the camera's near plane
+  actor.SetZ(distance - nearPlane);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a down signal where actor is closer than the camera's near plane
+  actor.SetZ((distance - nearPlane) + 1.0f);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a down signal where actor is just at the camera's far plane
+  actor.SetZ(distance - farPlane);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a down signal where actor is further than the camera's far plane
+  actor.SetZ((distance - farPlane) - 1.0f);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+  END_TEST;
+}
+
+int UtcDaliTouchDataEmitEmpty(void)
+{
+  TestApplication application;
+
+  try
+  {
+    // Emit an empty TouchEvent
+    Integration::TouchEvent event;
+    application.ProcessEvent( event );
+    tet_result( TET_FAIL );
+  }
+  catch ( Dali::DaliException& e )
+  {
+    DALI_TEST_ASSERT( e, "!event.points.empty()", TEST_LOCATION );
+  }
+  END_TEST;
+}
+
+int UtcDaliTouchDataInterrupted(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;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+
+  // Emit an interrupted signal, we should be signalled regardless of whether there is a hit or not.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Interrupted, Vector2( 200.0f, 200.0f /* Outside actor */ ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+
+  // Emit another interrupted signal, our signal handler should not be called.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Interrupted, Vector2( 200.0f, 200.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTouchDataParentConsumer(void)
+{
+  TestApplication application;
+  Actor rootActor( Stage::GetCurrent().GetRootLayer() );
+
+  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;
+  TouchDataFunctor functor( data, false );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Connect to root actor's touched signal
+  SignalData rootData;
+  TouchDataFunctor rootFunctor( rootData ); // Consumes signal
+  rootActor.TouchSignal().Connect( &application, rootFunctor );
+
+  Vector2 screenCoordinates( 10.0f, 10.0f );
+  Vector2 actorCoordinates, rootCoordinates;
+  actor.ScreenToLocal( actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+  rootActor.ScreenToLocal( rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, data.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, rootData.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, data.touchData.points[0].screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, rootData.touchData.points[0].screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( actorCoordinates, data.touchData.points[0].local, 0.1f, TEST_LOCATION );
+  DALI_TEST_EQUALS( rootCoordinates, rootData.touchData.points[0].local, 0.1f, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Emit a motion signal
+  screenCoordinates.x = screenCoordinates.y = 11.0f;
+  actor.ScreenToLocal( actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+  rootActor.ScreenToLocal( rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, screenCoordinates ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, data.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, rootData.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::MOTION, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::MOTION, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, data.touchData.points[0].screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, rootData.touchData.points[0].screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( actorCoordinates, data.touchData.points[0].local, 0.1f, TEST_LOCATION );
+  DALI_TEST_EQUALS( rootCoordinates, rootData.touchData.points[0].local, 0.1f, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Emit an up signal
+  screenCoordinates.x = screenCoordinates.y = 12.0f;
+  actor.ScreenToLocal( actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+  rootActor.ScreenToLocal( rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Up, screenCoordinates ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, data.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, rootData.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::UP, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::UP, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, data.touchData.points[0].screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, rootData.touchData.points[0].screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( actorCoordinates, data.touchData.points[0].local, 0.1f, TEST_LOCATION );
+  DALI_TEST_EQUALS( rootCoordinates, rootData.touchData.points[0].local, 0.1f, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Emit a down signal where the actor is not present, will hit the root actor though
+  screenCoordinates.x = screenCoordinates.y = 200.0f;
+  rootActor.ScreenToLocal( rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, screenCoordinates ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( 1u, rootData.touchData.GetPointCount(), TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( screenCoordinates, rootData.touchData.points[0].screen, TEST_LOCATION );
+  DALI_TEST_EQUALS( rootCoordinates, rootData.touchData.points[0].local, 0.1f, TEST_LOCATION );
+  DALI_TEST_CHECK( rootActor == rootData.touchData.points[0].hitActor );
+  END_TEST;
+}
+
+int UtcDaliTouchDataInterruptedParentConsumer(void)
+{
+  TestApplication application;
+  Actor rootActor( Stage::GetCurrent().GetRootLayer() );
+
+  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;
+  TouchDataFunctor functor( data, false );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Connect to root actor's touched signal
+  SignalData rootData;
+  TouchDataFunctor rootFunctor( rootData ); // Consumes signal
+  rootActor.TouchSignal().Connect( &application, rootFunctor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Emit an interrupted signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Interrupted, Vector2( 200.0f, 200.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Emit another down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, rootData.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+  rootData.Reset();
+
+  // Remove actor from Stage
+  Stage::GetCurrent().Remove( actor );
+  data.Reset();
+  rootData.Reset();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit an interrupted signal, only root actor's signal should be called.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Interrupted, Vector2( 200.0f, 200.0f /* Outside actor */ ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( rootActor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Emit another interrupted state, none of the signal's should be called.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Interrupted, Vector2( 200.0f, 200.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( false, rootData.functorCalled, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTouchDataLeave(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;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Set actor to require leave events
+  actor.SetLeaveRequired( true );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a motion signal outside of actor, should be signalled with a Leave
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 200.0f, 200.0f )) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::LEAVE, data.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+
+  // Another motion outside of actor, no signalling
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 201.0f, 201.0f )) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Another motion event inside actor, signalled with motion
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 10.0f, 10.0f )) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::MOTION, data.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+
+  // We do not want to listen to leave events anymore
+  actor.SetLeaveRequired( false );
+
+  // Another motion event outside of actor, no signalling
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 200.0f, 200.0f )) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+  END_TEST;
+}
+
+int UtcDaliTouchDataLeaveParentConsumer(void)
+{
+  TestApplication application;
+  Actor rootActor( Stage::GetCurrent().GetRootLayer() );
+
+  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;
+  TouchDataFunctor functor( data, false );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Connect to root actor's touched signal
+  SignalData rootData;
+  TouchDataFunctor rootFunctor( rootData ); // Consumes signal
+  rootActor.TouchSignal().Connect( &application, rootFunctor );
+
+  // Set actor to require leave events
+  actor.SetLeaveRequired( true );
+  rootActor.SetLeaveRequired( true );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Emit a motion signal outside of actor, should be signalled with a Leave
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 200.0f, 200.0f )) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::LEAVE, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::LEAVE, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Another motion outside of actor, only rootActor signalled
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 201.0f, 201.0f )) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::MOTION, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( rootActor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Another motion event inside actor, signalled with motion
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 10.0f, 10.0f )) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::MOTION, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::MOTION, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // We do not want to listen to leave events of actor anymore
+  actor.SetLeaveRequired( false );
+
+  // Another motion event outside of root actor, only root signalled
+  Vector2 stageSize( Stage::GetCurrent().GetSize() );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( stageSize.width + 10.0f, stageSize.height + 10.0f )) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::LEAVE, rootData.touchData.points[0].state, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTouchDataActorBecomesInsensitive(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;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+
+  // Change actor to insensitive
+  actor.SetSensitive( false );
+
+  // Emit a motion signal, signalled with an interrupted
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 200.0f, 200.0f )) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+  END_TEST;
+}
+
+int UtcDaliTouchDataActorBecomesInsensitiveParentConsumer(void)
+{
+  TestApplication application;
+  Actor rootActor( Stage::GetCurrent().GetRootLayer() );
+
+  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;
+  TouchDataFunctor functor( data, false );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Connect to root actor's touched signal
+  SignalData rootData;
+  TouchDataFunctor rootFunctor( rootData ); // Consumes signal
+  rootActor.TouchSignal().Connect( &application, rootFunctor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  data.Reset();
+  rootData.Reset();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Make root actor insensitive
+  rootActor.SetSensitive( false );
+
+  // Emit a motion signal, signalled with an interrupted (should get interrupted even if within root actor)
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2 ( 200.0f, 200.0f )) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, rootData.touchData.points[0].state, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTouchDataMultipleLayers(void)
+{
+  TestApplication application;
+  Actor rootActor( Stage::GetCurrent().GetRootLayer() );
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+
+  Layer layer1 ( Layer::New() );
+  layer1.SetSize(100.0f, 100.0f);
+  layer1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add( layer1 );
+
+  Actor actor1 ( Actor::New() );
+  actor1.SetSize( 100.0f, 100.0f );
+  actor1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  actor1.SetZ( 1.0f ); // Should hit actor1 in this layer
+  layer1.Add( actor1 );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to layer1 and actor1
+  layer1.TouchSignal().Connect( &application, functor );
+  actor1.TouchSignal().Connect( &application, functor );
+
+  // Hit in hittable area, actor1 should be hit
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( data.touchedActor == actor1 );
+  data.Reset();
+
+  // Make layer1 insensitive, nothing should be hit
+  layer1.SetSensitive( false );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Make layer1 sensitive again, again actor1 will be hit
+  layer1.SetSensitive( true );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( data.touchedActor == actor1 );
+  data.Reset();
+
+  // Make rootActor insensitive, nothing should be hit
+  rootActor.SetSensitive( false );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Make rootActor sensitive
+  rootActor.SetSensitive( true );
+
+  // Add another layer
+  Layer layer2 ( Layer::New() );
+  layer2.SetSize(100.0f, 100.0f );
+  layer2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  layer2.SetZ( 10.0f ); // Should hit layer2 in this layer rather than actor2
+  Stage::GetCurrent().Add( layer2 );
+
+  Actor actor2 ( Actor::New() );
+  actor2.SetSize(100.0f, 100.0f);
+  actor2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  layer2.Add( actor2 );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to layer2 and actor2
+  layer2.TouchSignal().Connect( &application, functor );
+  actor2.TouchSignal().Connect( &application, functor );
+
+  // Emit an event, should hit layer2
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  //DALI_TEST_CHECK( data.touchedActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
+  data.Reset();
+
+  // Make layer2 insensitive, should hit actor1
+  layer2.SetSensitive( false );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( data.touchedActor == actor1 );
+  data.Reset();
+
+  // Make layer2 sensitive again, should hit layer2
+  layer2.SetSensitive( true );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  //DALI_TEST_CHECK( data.touchedActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
+  data.Reset();
+
+  // Make layer2 invisible, render and notify
+  layer2.SetVisible( false );
+  application.SendNotification();
+  application.Render();
+
+  // Should hit actor1
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( data.touchedActor == actor1 );
+  data.Reset();
+
+  // Make rootActor invisible, render and notify
+  rootActor.SetVisible( false );
+  application.SendNotification();
+  application.Render();
+
+  // Should not hit anything
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+  END_TEST;
+}
+
+int UtcDaliTouchDataMultipleRenderTasks(void)
+{
+  TestApplication application;
+  Stage stage ( Stage::GetCurrent() );
+  Vector2 stageSize ( stage.GetSize() );
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  stage.Add(actor);
+
+  // Create render task
+  Viewport viewport( stageSize.width * 0.5f, stageSize.height * 0.5f, stageSize.width * 0.5f, stageSize.height * 0.5f );
+  RenderTask renderTask ( Stage::GetCurrent().GetRenderTaskList().CreateTask() );
+  renderTask.SetViewport( viewport );
+  renderTask.SetInputEnabled( true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Ensure renderTask actor can be hit too.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( viewport.x + 5.0f, viewport.y + 5.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Disable input on renderTask, should not be hittable
+  renderTask.SetInputEnabled( false );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( viewport.x + 5.0f, viewport.y + 5.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+  END_TEST;
+}
+
+int UtcDaliTouchDataMultipleRenderTasksWithChildLayer(void)
+{
+  TestApplication application;
+  Stage stage ( Stage::GetCurrent() );
+  Vector2 stageSize ( stage.GetSize() );
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  stage.Add(actor);
+
+  Layer layer = Layer::New();
+  layer.SetSize(100.0f, 100.0f);
+  layer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  actor.Add(layer);
+
+  // Create render task
+  Viewport viewport( stageSize.width * 0.5f, stageSize.height * 0.5f, stageSize.width * 0.5f, stageSize.height * 0.5f );
+  RenderTask renderTask ( Stage::GetCurrent().GetRenderTaskList().CreateTask() );
+  renderTask.SetViewport( viewport );
+  renderTask.SetInputEnabled( true );
+  renderTask.SetSourceActor( actor );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to layer's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+  layer.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Ensure renderTask actor can be hit too.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( viewport.x + 5.0f, viewport.y + 5.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Disable input on renderTask, should not be hittable
+  renderTask.SetInputEnabled( false );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( viewport.x + 5.0f, viewport.y + 5.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+  END_TEST;
+}
+
+int UtcDaliTouchDataOffscreenRenderTasks(void)
+{
+  TestApplication application;
+  Stage stage ( Stage::GetCurrent() );
+  Vector2 stageSize ( stage.GetSize() );
+
+  // FrameBufferImage for offscreen RenderTask
+  FrameBufferImage frameBufferImage( FrameBufferImage::New( stageSize.width, stageSize.height, Pixel::RGBA8888 ) );
+
+  // Create a renderable actor to display the FrameBufferImage
+  Actor renderableActor = CreateRenderableActor( frameBufferImage );
+  renderableActor.SetParentOrigin(ParentOrigin::CENTER);
+  renderableActor.SetSize( stageSize.x, stageSize.y );
+  renderableActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME
+  stage.Add( renderableActor );
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  stage.Add( actor );
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); // Ensure framebuffer connects
+
+  stage.GetRenderTaskList().GetTask( 0u ).SetScreenToFrameBufferFunction( RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION );
+
+  // Create a RenderTask
+  RenderTask renderTask = stage.GetRenderTaskList().CreateTask();
+  renderTask.SetSourceActor( actor );
+  renderTask.SetTargetFrameBuffer( frameBufferImage );
+  renderTask.SetInputEnabled( true );
+
+  // Create another RenderTask
+  RenderTask renderTask2( stage.GetRenderTaskList().CreateTask() );
+  renderTask2.SetInputEnabled( true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+  END_TEST;
+}
+
+int UtcDaliTouchDataMultipleRenderableActors(void)
+{
+  TestApplication application;
+  Stage stage ( Stage::GetCurrent() );
+  Vector2 stageSize ( stage.GetSize() );
+
+  Actor parent = CreateRenderableActor();
+  parent.SetSize(100.0f, 100.0f);
+  parent.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  stage.Add(parent);
+
+  Actor actor = CreateRenderableActor();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  parent.Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to layer's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+  parent.TouchSignal().Connect( &application, functor );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchedActor );
+  END_TEST;
+}
+
+int UtcDaliTouchDataActorRemovedInSignal(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;
+  RemoveActorFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Register for leave events
+  actor.SetLeaveRequired( true );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Re-add, render and notify
+  Stage::GetCurrent().Add(actor);
+  application.SendNotification();
+  application.Render();
+
+  // Emit another signal outside of actor's area, should not get anything as the scene has changed.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2( 210.0f, 210.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit another signal outside of actor's area, should not get anything as the scene has changed.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2( 210.0f, 210.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Re-add actor back to stage, render and notify
+  Stage::GetCurrent().Add(actor);
+  application.SendNotification();
+  application.Render();
+
+  // Emit another down event
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Completely delete the actor
+  actor.Reset();
+
+  // Emit event, should not crash and should not receive an event.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2( 210.0f, 210.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTouchDataActorSignalNotConsumed(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;
+  TouchDataFunctor functor( data, false );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTouchDataActorUnStaged(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;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Remove actor from stage
+  Stage::GetCurrent().Remove( actor );
+  data.Reset();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit a move at the same point, we should not be signalled.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+  END_TEST;
+}
+
+int UtcDaliTouchDataSystemOverlayActor(void)
+{
+  TestApplication application;
+  Dali::Integration::Core& core( application.GetCore() );
+  Dali::Integration::SystemOverlay& systemOverlay( core.GetSystemOverlay() );
+  systemOverlay.GetOverlayRenderTasks().CreateTask();
+
+  // Create an actor and add it to the system overlay.
+  Actor systemActor = Actor::New();
+  systemActor.SetSize(100.0f, 100.0f);
+  systemActor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  systemOverlay.Add( systemActor );
+
+  // Create an actor and add it to the stage as per normal, same position and size as systemActor
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(actor);
+
+  // Connect to the touch signals.
+  SignalData data;
+  TouchDataFunctor functor( data );
+  systemActor.TouchSignal().Connect( &application, functor );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit a down signal, the system overlay is drawn last so is at the top, should hit the systemActor.
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( systemActor == data.touchedActor );
+  END_TEST;
+}
+
+int UtcDaliTouchDataLayerConsumesTouch(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;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().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;
+}
+
+int UtcDaliTouchDataLeaveActorReadded(void)
+{
+  TestApplication application;
+  Stage stage = Stage::GetCurrent();
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  stage.Add(actor);
+
+  // Set actor to receive touch-events
+  actor.SetLeaveRequired( true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down and motion
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2( 11.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Remove actor from stage and add again
+  stage.Remove( actor );
+  stage.Add( actor );
+
+  // Emit a motion within the actor's bounds
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2( 12.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Emit a motion outside the actor's bounds
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2( 200.0f, 200.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::LEAVE, data.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliTouchDataStencilNonRenderableActor(void)
+{
+  TestApplication application;
+  Stage stage = Stage::GetCurrent();
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  stage.Add(actor);
+
+  Actor stencil = Actor::New();
+  stencil.SetSize(50.0f, 50.0f);
+  stencil.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  stencil.SetDrawMode( DrawMode::STENCIL );
+  stage.Add(stencil);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit an event within stencil area
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  // Emit an event outside the stencil area but within the actor area, we should have a hit!
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 60.0f, 60.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  data.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliTouchDataActorUnstaged(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;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  data.Reset();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Unparent the actor
+  actor.Unparent();
+
+  // Should receive an interrupted event
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTouchDataParentUnstaged(void)
+{
+  TestApplication application;
+
+  Actor parent = Actor::New();
+  parent.SetSize(100.0f, 100.0f);
+  parent.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(parent);
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  parent.Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  data.Reset();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Unparent the parent of the touchable actor
+  parent.Unparent();
+
+  // Should receive an interrupted event
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTouchDataActorUnstagedDifferentConsumer(void)
+{
+  TestApplication application;
+
+  Actor parent = Actor::New();
+  parent.SetSize(100.0f, 100.0f);
+  parent.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(parent);
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  parent.Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data, false /* Do not consume */ );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Connect to parent's touched signal
+  SignalData parentData;
+  TouchDataFunctor parentFunctor( parentData );
+  parent.TouchSignal().Connect( &application, parentFunctor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == data.touchedActor );
+  DALI_TEST_EQUALS( true, parentData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, parentData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == parentData.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( parent == parentData.touchedActor );
+  data.Reset();
+  parentData.Reset();
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Unparent the actor
+  actor.Unparent();
+
+  // Should receive an interrupted event for both actor & parent
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, parentData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, parentData.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+  parentData.Reset();
+
+  // Readd actor to parent
+  parent.Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit a motion signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Motion, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, parentData.functorCalled, TEST_LOCATION );
+  data.Reset();
+  parentData.Reset();
+
+  // Parent is now consumer, connect again to the touched signal of the actor so that it becomes the consumer
+  SignalData secondData;
+  TouchDataFunctor secondFunctor( secondData /* Consume */ );
+  actor.TouchSignal().Connect( &application, secondFunctor );
+
+  // Unparent the actor
+  actor.Unparent();
+
+  // Should receive an interrupted event for both actor functors & the parent as well as it was last consumer
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, parentData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, parentData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, secondData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, secondData.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+  parentData.Reset();
+  secondData.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliTouchDataInterruptedDifferentConsumer(void)
+{
+  TestApplication application;
+  Actor rootActor( Stage::GetCurrent().GetRootLayer() );
+
+  Actor parent = Actor::New();
+  parent.SetSize(100.0f, 100.0f);
+  parent.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(parent);
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  parent.Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's touched signal
+  SignalData data;
+  TouchDataFunctor functor( data, false /* Do not consume */ );
+  actor.TouchSignal().Connect( &application, functor );
+
+  // Connect to parent's touched signal
+  SignalData parentData;
+  TouchDataFunctor parentFunctor( parentData, false /* Do not consume */ );
+  parent.TouchSignal().Connect( &application, parentFunctor );
+
+  // Connect to root's touched signal and consume
+  SignalData rootData;
+  TouchDataFunctor rootFunctor( rootData );
+  rootActor.TouchSignal().Connect( &application, rootFunctor );
+
+  // Emit a down signal
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == data.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( actor == data.touchedActor );
+  DALI_TEST_EQUALS( true, parentData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, parentData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == parentData.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( parent == parentData.touchedActor );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::DOWN, rootData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_CHECK( actor == rootData.touchData.points[0].hitActor );
+  DALI_TEST_CHECK( rootActor == rootData.touchedActor );
+  data.Reset();
+  parentData.Reset();
+  rootData.Reset();
+
+  // Root is now consumer, connect to the touched signal of the parent so that it becomes the consumer
+  SignalData secondData;
+  TouchDataFunctor secondFunctor( secondData /* Consume */ );
+  parent.TouchSignal().Connect( &application, secondFunctor );
+
+  // Emit an interrupted signal, all three should STILL be called
+  application.ProcessEvent( GenerateSingleTouch( TouchPoint::Interrupted, Vector2( 10.0f, 10.0f ) ) );
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, data.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, parentData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, parentData.touchData.points[0].state, TEST_LOCATION );
+  DALI_TEST_EQUALS( true, rootData.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( PointState::INTERRUPTED, rootData.touchData.points[0].state, TEST_LOCATION );
+  data.Reset();
+  parentData.Reset();
+  rootData.Reset();
+
+  END_TEST;
+}
index 52ed83b..b306888 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/constants.h>
+#include <dali/public-api/events/touch-data.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/radian.h>
@@ -1731,7 +1732,7 @@ bool Actor::IsKeyboardFocusable() const
 
 bool Actor::GetTouchRequired() const
 {
-  return !mTouchedSignal.Empty() || mDerivedRequiresTouch;
+  return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch;
 }
 
 bool Actor::GetHoverRequired() const
@@ -1765,20 +1766,26 @@ bool Actor::IsGestureRequred( Gesture::Type type ) const
   return mGestureData && mGestureData->IsGestureRequred( type );
 }
 
-bool Actor::EmitTouchEventSignal( const TouchEvent& event )
+bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch )
 {
   bool consumed = false;
 
-  if( !mTouchedSignal.Empty() )
+  if( !mTouchSignal.Empty() )
   {
     Dali::Actor handle( this );
-    consumed = mTouchedSignal.Emit( handle, event );
+    consumed = mTouchSignal.Emit( handle, touch );
+  }
+
+  if( !mTouchedSignal.Empty() || !mTouchSignal.Empty() )
+  {
+    Dali::Actor handle( this );
+    consumed |= mTouchedSignal.Emit( handle, event );
   }
 
   if( !consumed )
   {
     // Notification for derived classes
-    consumed = OnTouchEvent( event );
+    consumed = OnTouchEvent( event ); // TODO
   }
 
   return consumed;
@@ -1824,9 +1831,15 @@ bool Actor::EmitWheelEventSignal( const WheelEvent& event )
 
 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
 {
+  DALI_LOG_WARNING( "Deprecated: Use TouchSignal() instead\n" );
   return mTouchedSignal;
 }
 
+Dali::Actor::TouchDataSignalType& Actor::TouchSignal()
+{
+  return mTouchSignal;
+}
+
 Dali::Actor::HoverSignalType& Actor::HoveredSignal()
 {
   return mHoveredSignal;
index 9eb1690..920cc1f 100644 (file)
@@ -39,7 +39,7 @@ namespace Dali
 {
 
 struct KeyEvent;
-struct TouchEvent;
+class TouchData;
 struct HoverEvent;
 struct WheelEvent;
 
@@ -1358,10 +1358,11 @@ public:
 
   /**
    * Used by the EventProcessor to emit touch event signals.
-   * @param[in] event The touch event.
+   * @param[in] event The touch event (Old API).
+   * @param[in] touch The touch data.
    * @return True if the event was consumed.
    */
-  bool EmitTouchEventSignal( const TouchEvent& event );
+  bool EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch );
 
   /**
    * Used by the EventProcessor to emit hover event signals.
@@ -1383,6 +1384,11 @@ public:
   Dali::Actor::TouchSignalType& TouchedSignal();
 
   /**
+   * @copydoc Dali::Actor::TouchEventSignal()
+   */
+  Dali::Actor::TouchDataSignalType& TouchSignal();
+
+  /**
    * @copydoc Dali::Actor::HoveredSignal()
    */
   Dali::Actor::HoverSignalType& HoveredSignal();
@@ -1795,6 +1801,7 @@ protected:
 
   // Signals
   Dali::Actor::TouchSignalType             mTouchedSignal;
+  Dali::Actor::TouchDataSignalType         mTouchSignal;
   Dali::Actor::HoverSignalType             mHoveredSignal;
   Dali::Actor::WheelEventSignalType        mWheelEventSignal;
   Dali::Actor::OnStageSignalType           mOnStageSignal;
index 2358018..fe95c3e 100644 (file)
@@ -36,6 +36,7 @@
 #include <dali/internal/event/common/object-registry-impl.h>
 #include <dali/integration-api/platform-abstraction.h>
 #include <dali/public-api/common/constants.h>
+#include <dali/public-api/events/touch-data.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 
@@ -541,9 +542,10 @@ void Stage::EmitEventProcessingFinishedSignal()
    mEventProcessingFinishedSignal.Emit();
 }
 
-void Stage::EmitTouchedSignal( const TouchEvent& touch )
+void Stage::EmitTouchedSignal( const TouchEvent& touchEvent, const Dali::TouchData& touch )
 {
-  mTouchedSignal.Emit( touch );
+  mTouchedSignal.Emit( touchEvent );
+  mTouchSignal.Emit( touch );
 }
 
 void Stage::EmitWheelEventSignal(const WheelEvent& event)
@@ -570,9 +572,15 @@ Dali::Stage::EventProcessingFinishedSignalType& Stage::EventProcessingFinishedSi
 
 Dali::Stage::TouchedSignalType& Stage::TouchedSignal()
 {
+  DALI_LOG_WARNING( "Deprecated. Use TouchSignal() instead." );
   return mTouchedSignal;
 }
 
+Dali::Stage::TouchSignalType& Stage::TouchSignal()
+{
+  return mTouchSignal;
+}
+
 Dali::Stage::WheelEventSignalType& Stage::WheelEventSignal()
 {
   return mWheelEventSignal;
index 33c7cc9..e2b4cb4 100644 (file)
@@ -301,9 +301,10 @@ public:
 
   /**
    * Emits the touched signal.
+   * @param[in] touchEvent The touch event details (Old API).
    * @param[in] touch The touch event details.
    */
-  void EmitTouchedSignal( const TouchEvent& touch );
+  void EmitTouchedSignal( const TouchEvent& touchEvent, const Dali::TouchData& touch );
 
   /**
    * Used by the EventProcessor to emit wheel event signals.
@@ -332,6 +333,11 @@ public:
   Dali::Stage::TouchedSignalType& TouchedSignal();
 
   /**
+    * @copydoc Dali::Stage::TouchSignal()
+    */
+  Dali::Stage::TouchSignalType& TouchSignal();
+
+  /**
    * @copydoc Dali::Stage::WheelEventSignal()
    */
   Dali::Stage::WheelEventSignalType& WheelEventSignal();
@@ -464,8 +470,9 @@ private:
   // The event processing finished signal
   Dali::Stage::EventProcessingFinishedSignalType  mEventProcessingFinishedSignal;
 
-  // The touched signal
+  // The touched signals
   Dali::Stage::TouchedSignalType                  mTouchedSignal;
+  Dali::Stage::TouchSignalType                    mTouchSignal;
 
   // The wheel event signal
   Dali::Stage::WheelEventSignalType               mWheelEventSignal;
diff --git a/dali/internal/event/events/touch-data-impl.cpp b/dali/internal/event/events/touch-data-impl.cpp
new file mode 100644 (file)
index 0000000..f076099
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015 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 <dali/internal/event/events/touch-data-impl.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+TouchData::TouchData()
+: mPoints(),
+  mTime( 0 )
+{
+}
+
+TouchData::TouchData( unsigned long time )
+: mPoints(),
+  mTime( time )
+{
+}
+
+TouchData::~TouchData()
+{
+}
+
+unsigned long TouchData::GetTime() const
+{
+  return mTime;
+}
+
+size_t TouchData::GetPointCount() const
+{
+  return mPoints.size();
+}
+
+int32_t TouchData::GetDeviceId( size_t point ) const
+{
+  if( point < mPoints.size() )
+  {
+    return mPoints[ point ].deviceId;
+  }
+  return -1;
+}
+
+PointState::Type TouchData::GetState( size_t point ) const
+{
+  if( point < mPoints.size() )
+  {
+    return static_cast< PointState::Type >( mPoints[ point ].state );
+  }
+  return PointState::FINISHED;
+}
+
+Dali::Actor TouchData::GetHitActor( size_t point ) const
+{
+  if( point < mPoints.size() )
+  {
+    return mPoints[ point ].hitActor;
+  }
+  return Dali::Actor();
+}
+
+const Vector2& TouchData::GetLocalPosition( size_t point ) const
+{
+  if( point < mPoints.size() )
+  {
+    return mPoints[ point ].local;
+  }
+  return Vector2::ZERO;
+}
+
+const Vector2& TouchData::GetScreenPosition( size_t point ) const
+{
+  if( point < mPoints.size() )
+  {
+    return mPoints[ point ].screen;
+  }
+  return Vector2::ZERO;
+}
+
+const TouchPoint& TouchData::GetPoint( size_t point ) const
+{
+  DALI_ASSERT_DEBUG( point < mPoints.size() && "No point at index" );
+  return mPoints[ point ];
+}
+
+void TouchData::AddPoint( const TouchPoint& point )
+{
+  mPoints.push_back( point );
+}
+
+void TouchData::SetPoints( const TouchPointContainer& points )
+{
+  mPoints = points;
+}
+
+} // namsespace Internal
+
+} // namespace Dali
diff --git a/dali/internal/event/events/touch-data-impl.h b/dali/internal/event/events/touch-data-impl.h
new file mode 100644 (file)
index 0000000..fb7589f
--- /dev/null
@@ -0,0 +1,162 @@
+#ifndef __DALI_INTERNAL_TOUCH_DATA_H__
+#define __DALI_INTERNAL_TOUCH_DATA_H__
+
+/*
+ * Copyright (c) 2016 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/events/point-state.h>
+#include <dali/public-api/events/touch-data.h>
+#include <dali/public-api/events/touch-point.h>
+#include <dali/public-api/object/base-object.h>
+
+namespace Dali
+{
+
+class Actor;
+struct Vector2;
+
+namespace Internal
+{
+
+/**
+ * @copydoc Dali::TouchData
+ */
+class TouchData : public BaseObject
+{
+public:
+
+  // Construction & Destruction
+
+  /**
+   * @brief Default constructor
+   */
+  TouchData();
+
+  /**
+   * @brief Constructor
+   * @param[in]  time  The time the event occurred
+   */
+  TouchData( unsigned long time );
+
+  /**
+   * @brief Destructor
+   */
+  ~TouchData();
+
+  // Getters
+
+  /**
+   * @copydoc Dali::TouchData::GetTime()
+   */
+  unsigned long GetTime() const;
+
+  /**
+   * @copydoc Dali::TouchData::GetPointCount()
+   */
+  size_t GetPointCount() const;
+
+  /**
+   * @copydoc Dali::TouchData::GetDeviceId()
+   */
+  int32_t GetDeviceId( size_t point ) const;
+
+  /**
+   * @copydoc Dali::TouchData::GetGetState()
+   */
+  PointState::Type GetState( size_t point  ) const;
+
+  /**
+   * @copydoc Dali::TouchData::GetHitActor()
+   */
+  Dali::Actor GetHitActor( size_t point ) const;
+
+  /**
+   * @copydoc Dali::TouchData::GetLocalPosition()
+   */
+  const Vector2& GetLocalPosition( size_t point ) const;
+
+  /**
+   * @copydoc Dali::TouchData::GetScreenPosition()
+   */
+  const Vector2& GetScreenPosition( size_t point ) const;
+
+  /**
+   * @brief Returns a reference to a point at the index requested.
+   *
+   * The first point in the set is always the primary point (i.e. the first point touched in a multi-touch event).
+   *
+   * @SINCE_1_1.36
+   * @param[in]  point  The index of the required Point.
+   * @return A reference to the Point at the position requested
+   * @note point should be less than the value returned by GetPointCount(). Will assert if out of range.
+   */
+  const TouchPoint& GetPoint( size_t point ) const;
+
+  // Setters
+
+  /**
+   * @brief Adds a point to this touch event handler.
+   * @param[in]  point  The point to add to the touch event handler.
+   */
+  void AddPoint( const TouchPoint& point );
+
+  /**
+   * @brief Overwrites the internal container with the point container specified.
+   *
+   * @param[in]  points  The point container.
+   */
+  void SetPoints( const TouchPointContainer& points );
+
+private:
+
+  /// Undefined Copy constructor
+  TouchData( const TouchData& other );
+
+  /// Undefined
+  TouchData& operator=( const TouchData& other );
+
+  TouchPointContainer mPoints;   ///< Container of the points for this touch event.
+  unsigned long       mTime;     ///< The time (in ms) that the touch event occurred.
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::TouchData& GetImplementation( Dali::TouchData& touchData )
+{
+  DALI_ASSERT_ALWAYS( touchData && "Touch Data handle is empty" );
+
+  BaseObject& object = touchData.GetBaseObject();
+
+  return static_cast< Internal::TouchData& >( object );
+}
+
+inline const Internal::TouchData& GetImplementation( const Dali::TouchData& touchData )
+{
+  DALI_ASSERT_ALWAYS( touchData && "Touch Data handle is empty" );
+
+  const BaseObject& object = touchData.GetBaseObject();
+
+  return static_cast< const Internal::TouchData& >( object );
+}
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_TOUCH_DATA_H__
index 0e58e54..0551ccd 100644 (file)
@@ -23,6 +23,7 @@
 #endif
 
 // INTERNAL INCLUDES
+#include <dali/public-api/events/touch-data.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/signals/callback.h>
 #include <dali/integration-api/debug.h>
@@ -32,6 +33,7 @@
 #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/events/touch-data-impl.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
 
 namespace Dali
@@ -58,10 +60,11 @@ const char * TOUCH_POINT_STATE[TouchPoint::Last] =
 
 #endif // defined(DEBUG_ENABLED)
 
+
 /**
  *  Recursively deliver events to the actor and its parents, until the event is consumed or the stage is reached.
  */
-Dali::Actor EmitTouchSignals( Dali::Actor actor, const TouchEvent& event )
+Dali::Actor EmitTouchSignals( Dali::Actor actor, const TouchEvent& event, const Dali::TouchData& touchData )
 {
   Dali::Actor consumedActor;
 
@@ -76,7 +79,7 @@ Dali::Actor EmitTouchSignals( Dali::Actor actor, const TouchEvent& event )
     // Only emit the signal if the actor's touch signal has connections (or derived actor implementation requires touch).
     if ( actorImpl.GetTouchRequired() )
     {
-      consumed = actorImpl.EmitTouchEventSignal( event );
+      consumed = actorImpl.EmitTouchEventSignal( event, touchData );
     }
 
     if ( consumed )
@@ -93,7 +96,7 @@ Dali::Actor EmitTouchSignals( Dali::Actor actor, const TouchEvent& event )
            (parent == oldParent) )
       {
         // One of the actor's parents may consumed the event and they should be set as the consumed actor.
-        consumedActor = EmitTouchSignals( parent, event );
+        consumedActor = EmitTouchSignals( parent, event, touchData );
       }
     }
   }
@@ -101,6 +104,19 @@ Dali::Actor EmitTouchSignals( Dali::Actor actor, const TouchEvent& event )
   return consumedActor;
 }
 
+Dali::Actor AllocAndEmitTouchSignals( unsigned long time,  Dali::Actor actor, const TouchPoint& point )
+{
+  TouchEvent touchEvent( time );
+  IntrusivePtr< TouchData > touchData( new TouchData( time ) );
+  Dali::TouchData touchDataHandle( touchData.Get() );
+
+  touchEvent.points.push_back( point );
+  touchData->AddPoint( point );
+
+  return EmitTouchSignals( actor, touchEvent, touchDataHandle );
+}
+
+
 /**
  * Changes the state of the primary point to leave and emits the touch signals
  */
@@ -119,7 +135,10 @@ Dali::Actor EmitTouchSignals( Actor* actor, RenderTask& renderTask, const TouchE
     primaryPoint.state = state;
   }
 
-  return EmitTouchSignals( Dali::Actor(actor), touchEvent );
+  IntrusivePtr< TouchData > touchData( new TouchData( touchEvent.time ) );
+  touchData->SetPoints( touchEvent.points );
+
+  return EmitTouchSignals( Dali::Actor(actor), touchEvent, Dali::TouchData( touchData.Get() ) );
 }
 
 } // unnamed namespace
@@ -149,23 +168,21 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
 
   PRINT_HIERARCHY(gLogFilter);
 
-  // Copy so we can add the results of a hit-test.
-  TouchEvent touchEvent( event.time );
-
   // 1) Check if it is an interrupted event - we should inform our last primary hit actor about this
   //    and emit the stage signal as well.
 
   if ( event.points[0].state == TouchPoint::Interrupted )
   {
     Dali::Actor consumingActor;
-    touchEvent.points.push_back(event.points[0]);
+    TouchPoint currentPoint( event.points[0] );
 
     Actor* lastPrimaryHitActor( mLastPrimaryHitActor.GetActor() );
     if ( lastPrimaryHitActor )
     {
       Dali::Actor lastPrimaryHitActorHandle( lastPrimaryHitActor );
-      touchEvent.points[0].hitActor = lastPrimaryHitActorHandle;
-      consumingActor = EmitTouchSignals( lastPrimaryHitActorHandle, touchEvent );
+      currentPoint.hitActor = lastPrimaryHitActorHandle;
+
+      consumingActor = AllocAndEmitTouchSignals( event.time, lastPrimaryHitActorHandle, currentPoint );
     }
 
     // If the last consumed actor was different to the primary hit actor then inform it as well (if it has not already been informed).
@@ -175,8 +192,8 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
          lastConsumedActor != consumingActor )
     {
       Dali::Actor lastConsumedActorHandle( lastConsumedActor );
-      touchEvent.points[0].hitActor = lastConsumedActorHandle;
-      EmitTouchSignals( lastConsumedActorHandle, touchEvent );
+      currentPoint.hitActor = lastConsumedActorHandle;
+      AllocAndEmitTouchSignals( event.time, lastConsumedActorHandle, currentPoint );
     }
 
     // Tell the touch-down consuming actor as well, if required
@@ -187,8 +204,9 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
          touchDownConsumedActor != consumingActor )
     {
       Dali::Actor touchDownConsumedActorHandle( touchDownConsumedActor );
-      touchEvent.points[0].hitActor = touchDownConsumedActorHandle;
-      EmitTouchSignals( touchDownConsumedActorHandle, touchEvent );
+
+      currentPoint.hitActor = touchDownConsumedActorHandle;
+      AllocAndEmitTouchSignals( event.time, touchDownConsumedActorHandle, currentPoint );
     }
 
     mLastPrimaryHitActor.SetActor( NULL );
@@ -196,13 +214,24 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
     mTouchDownConsumedActor.SetActor( NULL );
     mLastRenderTask.Reset();
 
-    touchEvent.points[0].hitActor.Reset();
-    mStage.EmitTouchedSignal( touchEvent );
+    currentPoint.hitActor.Reset();
+
+    TouchEvent touchEvent( event.time );
+    IntrusivePtr< TouchData > touchData( new TouchData( event.time ) );
+    Dali::TouchData touchDataHandle( touchData.Get() );
+
+    touchEvent.points.push_back( currentPoint );
+    touchData->AddPoint( currentPoint );
+
+    mStage.EmitTouchedSignal( touchEvent, touchDataHandle );
 
     return; // No need for hit testing
   }
 
   // 2) Hit Testing.
+  TouchEvent touchEvent( event.time );
+  IntrusivePtr< TouchData > touchData( new TouchData( event.time ) );
+  Dali::TouchData touchDataHandle( touchData.Get() );
 
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "\n" );
   DALI_LOG_INFO( gLogFilter, Debug::General, "Point(s): %d\n", event.GetPointCount() );
@@ -214,11 +243,11 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
     HitTestAlgorithm::Results hitTestResults;
     HitTestAlgorithm::HitTest( stage, iter->screen, hitTestResults );
 
-    TouchPoint newPoint( iter->deviceId, iter->state, iter->screen.x, iter->screen.y );
+    TouchPoint newPoint( iter->deviceId, iter->state, iter->screen.x, iter->screen.y, hitTestResults.actorCoordinates.x, hitTestResults.actorCoordinates.y );
     newPoint.hitActor = hitTestResults.actor;
-    newPoint.local = hitTestResults.actorCoordinates;
 
     touchEvent.points.push_back( newPoint );
+    touchData->AddPoint( newPoint );
 
     DALI_LOG_INFO( gLogFilter, Debug::General, "  State(%s), Screen(%.0f, %.0f), HitActor(%p, %s), Local(%.2f, %.2f)\n",
                    TOUCH_POINT_STATE[iter->state], iter->screen.x, iter->screen.y,
@@ -239,7 +268,7 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
   Dali::Actor consumedActor;
   if ( currentRenderTask )
   {
-    consumedActor = EmitTouchSignals( touchEvent.points[0].hitActor, touchEvent );
+    consumedActor = EmitTouchSignals( touchEvent.points[0].hitActor, touchEvent, touchDataHandle );
   }
 
   TouchPoint& primaryPoint = touchEvent.points[0];
@@ -369,13 +398,12 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
              touchDownConsumedActor != lastConsumedActor )
         {
           Dali::Actor touchDownConsumedActorHandle( touchDownConsumedActor );
-          touchEvent.points[0].hitActor = touchDownConsumedActorHandle;
-          touchEvent.points[0].state = TouchPoint::Interrupted;
-          EmitTouchSignals( touchDownConsumedActorHandle, touchEvent );
 
-          // Restore touch-event to original state
-          touchEvent.points[0].hitActor = primaryHitActor;
-          touchEvent.points[0].state = primaryPointState;
+          TouchPoint currentPoint = touchData->GetPoint( 0 );
+          currentPoint.hitActor = touchDownConsumedActorHandle;
+          currentPoint.state    = TouchPoint::Interrupted;
+
+          AllocAndEmitTouchSignals( event.time, touchDownConsumedActorHandle, currentPoint );
         }
 
         mTouchDownConsumedActor.SetActor( NULL );
@@ -384,7 +412,7 @@ void TouchEventProcessor::ProcessTouchEvent( const Integration::TouchEvent& even
 
       case TouchPoint::Down:
       {
-        mStage.EmitTouchedSignal( touchEvent );
+        mStage.EmitTouchedSignal( touchEvent, touchDataHandle );
         break;
       }
 
@@ -410,11 +438,15 @@ void TouchEventProcessor::OnObservedActorDisconnected( Actor* actor )
     touchEvent.points.push_back( TouchPoint( 0, TouchPoint::Interrupted, 0.0f, 0.0f ) );
     touchEvent.points[0].hitActor = handle;
 
-    Dali::Actor eventConsumer = EmitTouchSignals( handle, touchEvent );
+    IntrusivePtr< TouchData > touchData( new TouchData );
+    touchData->SetPoints( touchEvent.points );
+
+    Dali::TouchData touchDataHandle( touchData.Get() );
+    Dali::Actor eventConsumer = EmitTouchSignals( handle, touchEvent, touchDataHandle );
 
     if ( mLastConsumedActor.GetActor() != eventConsumer )
     {
-      EmitTouchSignals( Dali::Actor( mLastConsumedActor.GetActor() ), touchEvent );
+      EmitTouchSignals( Dali::Actor( mLastConsumedActor.GetActor() ), touchEvent, touchDataHandle );
     }
 
     // Do not set mLastPrimaryHitActor to NULL we may be iterating through its observers
index 401fb1e..8cb6523 100644 (file)
@@ -61,6 +61,7 @@ internal_src_files = \
   $(internal_src_dir)/event/events/pinch-gesture-processor.cpp \
   $(internal_src_dir)/event/events/tap-gesture-detector-impl.cpp \
   $(internal_src_dir)/event/events/tap-gesture-processor.cpp \
+  $(internal_src_dir)/event/events/touch-data-impl.cpp \
   $(internal_src_dir)/event/events/touch-event-processor.cpp \
   $(internal_src_dir)/event/images/atlas-impl.cpp \
   $(internal_src_dir)/event/images/bitmap-packed-pixel.cpp \
index 7a7d0bd..25628ee 100644 (file)
@@ -539,6 +539,11 @@ Actor::TouchSignalType& Actor::TouchedSignal()
   return GetImplementation(*this).TouchedSignal();
 }
 
+Actor::TouchDataSignalType& Actor::TouchSignal()
+{
+  return GetImplementation( *this ).TouchSignal();
+}
+
 Actor::HoverSignalType& Actor::HoveredSignal()
 {
   return GetImplementation(*this).HoveredSignal();
index 24ce48f..b01ff3d 100644 (file)
@@ -46,6 +46,7 @@ struct Degree;
 class Quaternion;
 class Layer;
 struct KeyEvent;
+class TouchData;
 struct TouchEvent;
 struct HoverEvent;
 struct WheelEvent;
@@ -312,12 +313,13 @@ public:
 
   // Typedefs
 
-  typedef Signal< bool (Actor, const TouchEvent&)> TouchSignalType;                 ///< Touch signal type @SINCE_1_0.0
-  typedef Signal< bool (Actor, const HoverEvent&)> HoverSignalType;                 ///< Hover signal type @SINCE_1_0.0
-  typedef Signal< bool (Actor, const WheelEvent&) > WheelEventSignalType;           ///< Wheel signal type @SINCE_1_0.0
-  typedef Signal< void (Actor) > OnStageSignalType;  ///< Stage connection signal type @SINCE_1_0.0
-  typedef Signal< void (Actor) > OffStageSignalType; ///< Stage disconnection signal type @SINCE_1_0.0
-  typedef Signal< void (Actor) > OnRelayoutSignalType; ///< Called when the actor is relaid out @SINCE_1_0.0
+  typedef Signal< bool (Actor, const TouchEvent&) > TouchSignalType;        ///< @DEPRECATED_1_1.37 @brief Touch signal type @SINCE_1_0.0
+  typedef Signal< bool (Actor, const TouchData&) >  TouchDataSignalType;    ///< Touch signal type @SINCE_1_1.37
+  typedef Signal< bool (Actor, const HoverEvent&) > HoverSignalType;        ///< Hover signal type @SINCE_1_0.0
+  typedef Signal< bool (Actor, const WheelEvent&) > WheelEventSignalType;   ///< Wheel signal type @SINCE_1_0.0
+  typedef Signal< void (Actor) > OnStageSignalType;                         ///< Stage connection signal type @SINCE_1_0.0
+  typedef Signal< void (Actor) > OffStageSignalType;                        ///< Stage disconnection signal type @SINCE_1_0.0
+  typedef Signal< void (Actor) > OnRelayoutSignalType;                      ///< Called when the actor is relaid out @SINCE_1_0.0
 
   // Creation
 
@@ -1142,7 +1144,7 @@ public:
   // Input Handling
 
   /**
-   * @brief Sets whether an actor should emit touch or hover signals; see SignalTouch() and SignalHover().
+   * @brief Sets whether an actor should emit touch or hover signals.
    *
    * An actor is sensitive by default, which means that as soon as an application connects to the SignalTouch(),
    * the touch event signal will be emitted, and as soon as an application connects to the SignalHover(), the
@@ -1438,6 +1440,7 @@ public: // Renderer
 public: // Signals
 
   /**
+   * @DEPRECATED_1_1.37 Use TouchSignal() instead.
    * @brief This signal is emitted when touch input is received.
    *
    * A callback of the following type may be connected:
@@ -1453,6 +1456,21 @@ public: // Signals
   TouchSignalType& TouchedSignal();
 
   /**
+   * @brief This signal is emitted when touch input is received.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   bool YourCallbackName( Actor actor, TouchData& touch );
+   * @endcode
+   * The return value of True, indicates that the touch event has been consumed.
+   * Otherwise the signal will be emitted on the next sensitive parent of the actor.
+   * @SINCE_1_1.37
+   * @return The signal to connect to.
+   * @pre The Actor has been initialized.
+   */
+  TouchDataSignalType& TouchSignal();
+
+  /**
    * @brief This signal is emitted when hover input is received.
    *
    * A callback of the following type may be connected:
index 2f3e256..df137c4 100644 (file)
@@ -171,6 +171,8 @@ public:
   virtual void OnSizeAnimation(Animation& animation, const Vector3& targetSize) = 0;
 
   /**
+   * @DEPRECATED_1_1.37 Connect to TouchSignal() instead.
+   *
    * @brief Called after a touch-event is received by the owning actor.
    *
    * @SINCE_1_0.0
index 9a1e43f..3d809a0 100644 (file)
@@ -149,6 +149,11 @@ Stage::TouchedSignalType& Stage::TouchedSignal()
   return GetImplementation(*this).TouchedSignal();
 }
 
+Stage::TouchSignalType& Stage::TouchSignal()
+{
+  return GetImplementation( *this ).TouchSignal();
+}
+
 Stage::WheelEventSignalType& Stage::WheelEventSignal()
 {
   return GetImplementation(*this).WheelEventSignal();
index dab6243..50e7930 100644 (file)
@@ -37,6 +37,7 @@ class Stage;
 class Actor;
 class Layer;
 class ObjectRegistry;
+class TouchData;
 class RenderTaskList;
 struct Vector2;
 struct Vector3;
@@ -66,12 +67,13 @@ class DALI_IMPORT_API Stage : public BaseHandle
 {
 public:
 
-  typedef Signal< void (const KeyEvent&)> KeyEventSignalType;     ///< Key event signal type @SINCE_1_0.0
-  typedef Signal< void () > EventProcessingFinishedSignalType;    ///< Event Processing finished signal type @SINCE_1_0.0
-  typedef Signal< void (const TouchEvent&)> TouchedSignalType;    ///< Touched signal type @SINCE_1_0.0
-  typedef Signal< void (const WheelEvent&)> WheelEventSignalType; ///< Touched signal type @SINCE_1_0.0
-  typedef Signal< void () > ContextStatusSignal;                  ///< Context status signal type @SINCE_1_0.0
-  typedef Signal< void () > SceneCreatedSignalType;               ///< Scene created signal type @SINCE_1_0.0
+  typedef Signal< void (const KeyEvent&) > KeyEventSignalType;       ///< Key event signal type @SINCE_1_0.0
+  typedef Signal< void () > EventProcessingFinishedSignalType;       ///< Event Processing finished signal type @SINCE_1_0.0
+  typedef Signal< void (const TouchEvent&) > TouchedSignalType;      ///< @DEPRECATED_1_1.37 @brief Touched signal type @SINCE_1_0.0
+  typedef Signal< void (const TouchData&) > TouchSignalType;                ///< Touch signal type @SINCE_1_1.37
+  typedef Signal< void (const WheelEvent&) > WheelEventSignalType;   ///< Touched signal type @SINCE_1_0.0
+  typedef Signal< void () > ContextStatusSignal;                     ///< Context status signal type @SINCE_1_0.0
+  typedef Signal< void () > SceneCreatedSignalType;                  ///< Scene created signal type @SINCE_1_0.0
 
   static const Vector4 DEFAULT_BACKGROUND_COLOR; ///< Default black background.
   static const Vector4 DEBUG_BACKGROUND_COLOR;   ///< Green background, useful when debugging.
@@ -267,12 +269,13 @@ public:
   EventProcessingFinishedSignalType& EventProcessingFinishedSignal();
 
   /**
+   * @DEPRECATED_1_1.37 Use TouchSignal() instead.
    * @brief This signal is emitted when the screen is touched and when the touch ends
    * (i.e. the down & up touch events only).
    *
    * If there are multiple touch points, then this will be emitted when the first touch occurs and
    * then when the last finger is lifted.
-   * An interrupted event will also be emitted.
+   * An interrupted event will also be emitted (if it occurs).
    * A callback of the following type may be connected:
    * @code
    *   void YourCallbackName(const TouchEvent& event);
@@ -285,6 +288,24 @@ public:
   TouchedSignalType& TouchedSignal();
 
   /**
+   * @brief This signal is emitted when the screen is touched and when the touch ends
+   * (i.e. the down & up touch events only).
+   *
+   * If there are multiple touch points, then this will be emitted when the first touch occurs and
+   * then when the last finger is lifted.
+   * An interrupted event will also be emitted (if it occurs).
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName( TouchData event );
+   * @endcode
+   *
+   * @SINCE_1_1.37
+   * @return The touch signal to connect to.
+   * @note Motion events are not emitted.
+   */
+  TouchSignalType& TouchSignal();
+
+  /**
    * @brief This signal is emitted when wheel event is received.
    *
    * A callback of the following type may be connected:
index 430b99c..643a1a0 100644 (file)
 #include <dali/public-api/events/pan-gesture.h>
 #include <dali/public-api/events/pinch-gesture-detector.h>
 #include <dali/public-api/events/pinch-gesture.h>
+#include <dali/public-api/events/point-state.h>
 #include <dali/public-api/events/tap-gesture-detector.h>
 #include <dali/public-api/events/tap-gesture.h>
+#include <dali/public-api/events/touch-data.h>
 #include <dali/public-api/events/touch-event.h>
 #include <dali/public-api/events/touch-point.h>
 
diff --git a/dali/public-api/events/point-state.h b/dali/public-api/events/point-state.h
new file mode 100644 (file)
index 0000000..a3a7ac3
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __DALI_POINT_STATE_H__
+#define __DALI_POINT_STATE_H__
+
+/*
+ * Copyright (c) 2016 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.
+ *
+ */
+
+namespace Dali
+{
+/**
+ * @addtogroup dali_core_events
+ * @{
+ */
+
+/**
+ * @brief Point state
+ * @SINCE_1_1.37
+ */
+namespace PointState
+{
+
+/**
+ * @brief Point state type
+ * @SINCE_1_1.37
+ */
+enum Type
+{
+  STARTED,        /**< Touch or hover started */
+  FINISHED,       /**< Touch or hover finished */
+  DOWN = STARTED, /**< Screen touched */
+  UP = FINISHED,  /**< Touch stopped */
+  MOTION,         /**< Finger dragged or hovered */
+  LEAVE,          /**< Leave the boundary of an actor */
+  STATIONARY,     /**< No change from last event.  Useful when a multi-point event occurs where
+                       all points are sent but indicates that this particular point has not changed
+                       since the last time */
+  INTERRUPTED,    /**< A system event has occurred which has interrupted the touch or hover event sequence. */
+};
+}
+
+/**
+ * @}
+ */
+} // namespace Dali
+
+#endif // __DALI_POINT_H__
diff --git a/dali/public-api/events/touch-data.cpp b/dali/public-api/events/touch-data.cpp
new file mode 100644 (file)
index 0000000..7f15af4
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 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 <dali/public-api/events/touch-data.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/internal/event/events/touch-data-impl.h>
+
+#include <cstdio>
+
+namespace Dali
+{
+
+TouchData::TouchData()
+: BaseHandle()
+{
+}
+
+TouchData::TouchData( const TouchData& other )
+: BaseHandle( other )
+{
+}
+
+TouchData::~TouchData()
+{
+}
+
+TouchData& TouchData::operator=( const TouchData& other )
+{
+  BaseHandle::operator=( other );
+  return *this;
+}
+
+unsigned long TouchData::GetTime() const
+{
+  return GetImplementation( *this ).GetTime();
+}
+
+size_t TouchData::GetPointCount() const
+{
+  return GetImplementation( *this ).GetPointCount();
+}
+
+int32_t TouchData::GetDeviceId( size_t point ) const
+{
+  return GetImplementation( *this ).GetDeviceId( point );
+}
+
+PointState::Type TouchData::GetState( size_t point ) const
+{
+  return GetImplementation( *this ).GetState( point );
+}
+
+Actor TouchData::GetHitActor( size_t point ) const
+{
+  return GetImplementation( *this ).GetHitActor( point );
+}
+
+const Vector2& TouchData::GetLocalPosition( size_t point ) const
+{
+  return GetImplementation( *this ).GetLocalPosition( point );
+}
+
+const Vector2& TouchData::GetScreenPosition( size_t point ) const
+{
+  return GetImplementation( *this ).GetScreenPosition( point );
+}
+
+TouchData::TouchData( Internal::TouchData* internal )
+: BaseHandle( internal )
+{
+}
+
+} // namespace Dali
diff --git a/dali/public-api/events/touch-data.h b/dali/public-api/events/touch-data.h
new file mode 100644 (file)
index 0000000..7b1cfd2
--- /dev/null
@@ -0,0 +1,188 @@
+#ifndef __DALI_TOUCH_DATA_H__
+#define __DALI_TOUCH_DATA_H__
+
+/*
+ * Copyright (c) 2016 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <stdint.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/events/point-state.h>
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+
+namespace Internal DALI_INTERNAL
+{
+class TouchData;
+}
+
+/**
+ * @addtogroup dali_core_events
+ * @{
+ */
+
+class Actor;
+struct Vector2;
+
+/**
+ * @brief Touch events are a collection of points at a specific moment in time.
+ *
+ * When a multi-touch event occurs, each point represents the points that are currently being
+ * touched or the points where a touch has stopped.
+ *
+ * The first point is the primary point that's used for hit-testing.
+ * @SINCE_1_1.37
+ * @note Should not use this in a TouchData container as it is just a handle and the internal object can change.
+ */
+class DALI_IMPORT_API TouchData : public BaseHandle
+{
+public:
+
+  // Construction & Destruction
+
+  /**
+   * @brief An uninitialized TouchData instance.
+   *
+   * Calling member functions with an uninitialized TouchData handle is not allowed.
+   * @SINCE_1_1.37
+   */
+  TouchData();
+
+  /**
+   * @brief Copy constructor
+   *
+   * @SINCE_1_1.37
+   * @param[in]  other  The TouchEventHandle to copy from.
+   */
+  TouchData( const TouchData& other );
+
+  /**
+   * @brief Destructor
+   *
+   * @SINCE_1_1.37
+   */
+  ~TouchData();
+
+  // Operators
+
+  /**
+   * @brief Assignment Operator
+   *
+   * @SINCE_1_1.37
+   * @param[in]  other  The TouchEventHandle to copy from.
+   */
+  TouchData& operator=( const TouchData& other );
+
+  // Getters
+
+  /**
+   * @brief Returns the time (in ms) that the touch event occurred.
+   *
+   * @SINCE_1_1.37
+   * @return The time (in ms) that the touch event occurred.
+   */
+  unsigned long GetTime() const;
+
+  /**
+   * @brief Returns the total number of points in this TouchEventHandle.
+   *
+   * @SINCE_1_1.37
+   * @return Total number of Points.
+   */
+  size_t GetPointCount() const;
+
+  /**
+   * @brief Returns the ID of the device used for the Point specified.
+   *
+   * Each point has a unique device ID which specifies the device used for that
+   * point. This is returned by this method.
+   *
+   * @SINCE_1_1.37
+   * @param[in]  point  The point required.
+   * @return The Device ID of this point.
+   * @note If point is greater than GetPointCount() then this method will return -1.
+   */
+  int32_t GetDeviceId( size_t point ) const;
+
+  /**
+   * @brief Retrieves the State of the point specified.
+   *
+   * @SINCE_1_1.37
+   * @param[in]  point  The point required.
+   * @return The state of the point specified.
+   * @note If point is greater than GetPointCount() then this method will
+   * return PointState::FINISHED.
+   * @see State
+   */
+  PointState::Type GetState( size_t point ) const;
+
+  /**
+   * @brief Retrieve the actor that was underneath the point specified.
+   *
+   * @SINCE_1_1.37
+   * @param[in]  point  The point required.
+   * @return The actor that was underneath the point specified.
+   * @note If point is greater than GetPointCount() then this method will return
+   * an empty handle.
+   */
+  Actor GetHitActor( size_t point ) const;
+
+  /**
+   * @brief Retrieve the co-ordinates relative to the top-left of the hit-actor at the point specified.
+   *
+   * @SINCE_1_1.37
+   * @param[in]  point  The point required.
+   * @return The co-ordinates relative to the top-left of the hit-actor of the point specified.
+   *
+   * @note The top-left of an actor is (0.0, 0.0, 0.5).
+   * @note If you require the local coordinates of another actor (e.g the parent of the hit actor),
+   * then you should use Actor::ScreenToLocal().
+   * @note If point is greater than GetPointCount() then this method will return Vector2::ZERO.
+   */
+  const Vector2& GetLocalPosition( size_t point ) const;
+
+  /**
+   * @brief Retrieves the co-ordinates relative to the top-left of the screen of the point specified.
+   *
+   * @SINCE_1_1.37
+   * @param[in]  point  The point required.
+   * @return The co-ordinates relative to the top-left of the screen of the point specified.
+   * @note If point is greater than GetPointCount() then this method will return Vector2::ZERO.
+   */
+  const Vector2& GetScreenPosition( size_t point ) const;
+
+public: // Not intended for application developers
+
+  /**
+   * @brief This constructor is used internally to Create an initialized TouchData handle.
+   *
+   * @SINCE_1_1.37
+   * @param [in] touchData A pointer to a newly allocated Dali resource
+   */
+  explicit DALI_INTERNAL TouchData( Internal::TouchData* touchData );
+};
+
+/**
+ * @}
+ */
+} // namespace Dali
+
+#endif // __DALI_TOUCH_DATA_H__
index 3fc4463..e7d9926 100644 (file)
@@ -30,6 +30,8 @@ namespace Dali
  */
 
 /**
+ * @DEPRECATED_1_1.37 Use TouchEventHandle instead
+ *
  * @brief Touch events are a collection of touch points at a specific moment in time.
  *
  * When a multi-touch event occurs, each touch point represents the points that are currently being
@@ -41,12 +43,14 @@ struct DALI_IMPORT_API TouchEvent
   // Construction & Destruction
 
   /**
+   * @DEPRECATED_1_1.37
    * @brief Default constructor
    * @SINCE_1_0.0
    */
   TouchEvent();
 
   /**
+   * @DEPRECATED_1_1.37
    * @brief Constructor
    * @SINCE_1_0.0
    * @param[in] time The time the event occurred
@@ -54,6 +58,7 @@ struct DALI_IMPORT_API TouchEvent
   TouchEvent(unsigned long time);
 
   /**
+   * @DEPRECATED_1_1.37
    * @brief Destructor
    * @SINCE_1_0.0
    */
@@ -62,6 +67,7 @@ struct DALI_IMPORT_API TouchEvent
   // Data
 
   /**
+   * @DEPRECATED_1_1.37
    * @brief This is a container of points for this touch event.
    *
    * The first point in the set is always the
@@ -70,6 +76,7 @@ struct DALI_IMPORT_API TouchEvent
   TouchPointContainer points;
 
   /**
+   * @DEPRECATED_1_1.37
    * @brief The time (in ms) that the touch event occurred.
    */
   unsigned long time;
@@ -77,6 +84,7 @@ struct DALI_IMPORT_API TouchEvent
   // Convenience Methods
 
   /**
+   * @DEPRECATED_1_1.37
    * @brief Returns the total number of points in this TouchEvent.
    *
    * @SINCE_1_0.0
@@ -85,6 +93,7 @@ struct DALI_IMPORT_API TouchEvent
   unsigned int GetPointCount() const;
 
   /**
+   * @DEPRECATED_1_1.37
    * @brief Returns a touch point at the index requested.
    *
    * The first point in the set is always the primary
index 707a51e..7b39802 100644 (file)
@@ -37,6 +37,7 @@ public_api_src_files = \
   $(public_api_src_dir)/events/tap-gesture-detector.cpp \
   $(public_api_src_dir)/events/touch-point.cpp \
   $(public_api_src_dir)/events/touch-event.cpp \
+  $(public_api_src_dir)/events/touch-data.cpp \
   $(public_api_src_dir)/images/image.cpp \
   $(public_api_src_dir)/images/pixel.cpp \
   $(public_api_src_dir)/images/buffer-image.cpp \
@@ -137,10 +138,12 @@ public_api_core_events_header_files = \
   $(public_api_src_dir)/events/pan-gesture-detector.h \
   $(public_api_src_dir)/events/pinch-gesture.h \
   $(public_api_src_dir)/events/pinch-gesture-detector.h \
+  $(public_api_src_dir)/events/point-state.h \
   $(public_api_src_dir)/events/tap-gesture.h \
   $(public_api_src_dir)/events/tap-gesture-detector.h \
   $(public_api_src_dir)/events/touch-point.h \
-  $(public_api_src_dir)/events/touch-event.h
+  $(public_api_src_dir)/events/touch-event.h \
+  $(public_api_src_dir)/events/touch-data.h
 
 public_api_core_images_header_files = \
   $(public_api_src_dir)/images/buffer-image.h \