Gesture event refactor 91/203091/22
authorDaniel McEwen <d.mcewen@partner.samsung.com>
Tue, 9 Apr 2019 13:44:44 +0000 (14:44 +0100)
committerDaniel McEwen <d.mcewen@partner.samsung.com>
Thu, 9 May 2019 18:06:45 +0000 (19:06 +0100)
All gesture work moved into core from adaptor

Change-Id: I2e5b46d788087c85a1eb868cd726dcfa7d81874b

80 files changed:
automated-tests/src/dali-internal/CMakeLists.txt
automated-tests/src/dali/CMakeLists.txt
automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.h
automated-tests/src/dali/dali-test-suite-utils/test-application.cpp
automated-tests/src/dali/dali-test-suite-utils/test-application.h
automated-tests/src/dali/dali-test-suite-utils/test-gesture-generator.cpp [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-gesture-generator.h [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.cpp [deleted file]
automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.h [deleted file]
automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp
automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.h
automated-tests/src/dali/utc-Dali-GestureDetector.cpp
automated-tests/src/dali/utc-Dali-LongPressGestureDetector.cpp
automated-tests/src/dali/utc-Dali-LongPressGestureRecognizer.cpp [new file with mode: 0644]
automated-tests/src/dali/utc-Dali-PanGestureDetector.cpp
automated-tests/src/dali/utc-Dali-PanGestureRecognizer.cpp [new file with mode: 0644]
automated-tests/src/dali/utc-Dali-PinchGestureDetector.cpp
automated-tests/src/dali/utc-Dali-PinchGestureRecognizer.cpp [new file with mode: 0644]
automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp
automated-tests/src/dali/utc-Dali-TapGestureRecognizer.cpp [new file with mode: 0644]
automated-tests/src/dali/utc-Dali-TypeRegistry.cpp
build/tizen/dali-core/Makefile.am
dali/integration-api/CMakeLists.txt
dali/integration-api/core.cpp
dali/integration-api/core.h
dali/integration-api/events/event.h
dali/integration-api/events/hover-event-integ.cpp
dali/integration-api/events/hover-event-integ.h
dali/integration-api/events/multi-point-event-integ.cpp
dali/integration-api/events/multi-point-event-integ.h
dali/integration-api/events/touch-event-combiner.cpp
dali/integration-api/events/touch-event-combiner.h
dali/integration-api/events/touch-event-integ.cpp
dali/integration-api/events/touch-event-integ.h
dali/integration-api/file.list
dali/integration-api/input-options.cpp
dali/integration-api/input-options.h
dali/integration-api/platform-abstraction.h
dali/internal/CMakeLists.txt
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/event/common/thread-local-storage.cpp
dali/internal/event/events/event-processor.cpp
dali/internal/event/events/event-processor.h
dali/internal/event/events/gesture-detector-impl.cpp
dali/internal/event/events/gesture-detector-impl.h
dali/internal/event/events/gesture-event-processor.cpp
dali/internal/event/events/gesture-event-processor.h
dali/internal/event/events/gesture-event.cpp [moved from dali/integration-api/events/gesture-event.cpp with 79% similarity]
dali/internal/event/events/gesture-event.h [moved from dali/integration-api/events/gesture-event.h with 82% similarity]
dali/internal/event/events/gesture-processor.cpp
dali/internal/event/events/gesture-processor.h
dali/internal/event/events/gesture-recognizer.h [new file with mode: 0644]
dali/internal/event/events/gesture-requests.h [moved from dali/integration-api/events/gesture-requests.h with 85% similarity]
dali/internal/event/events/long-press-gesture-event.cpp [moved from dali/integration-api/events/long-press-gesture-event.cpp with 83% similarity]
dali/internal/event/events/long-press-gesture-event.h [moved from dali/integration-api/events/long-press-gesture-event.h with 82% similarity]
dali/internal/event/events/long-press-gesture-processor.cpp
dali/internal/event/events/long-press-gesture-processor.h
dali/internal/event/events/long-press-gesture-recognizer.cpp [new file with mode: 0644]
dali/internal/event/events/long-press-gesture-recognizer.h [new file with mode: 0644]
dali/internal/event/events/pan-gesture-event.cpp [moved from dali/integration-api/events/pan-gesture-event.cpp with 83% similarity]
dali/internal/event/events/pan-gesture-event.h [moved from dali/integration-api/events/pan-gesture-event.h with 85% similarity]
dali/internal/event/events/pan-gesture-processor.cpp
dali/internal/event/events/pan-gesture-processor.h
dali/internal/event/events/pan-gesture-recognizer.cpp [new file with mode: 0644]
dali/internal/event/events/pan-gesture-recognizer.h [new file with mode: 0644]
dali/internal/event/events/pinch-gesture-event.cpp [moved from dali/integration-api/events/pinch-gesture-event.cpp with 84% similarity]
dali/internal/event/events/pinch-gesture-event.h [moved from dali/integration-api/events/pinch-gesture-event.h with 82% similarity]
dali/internal/event/events/pinch-gesture-processor.cpp
dali/internal/event/events/pinch-gesture-processor.h
dali/internal/event/events/pinch-gesture-recognizer.cpp [new file with mode: 0644]
dali/internal/event/events/pinch-gesture-recognizer.h [new file with mode: 0644]
dali/internal/event/events/tap-gesture-event.cpp [moved from dali/integration-api/events/tap-gesture-event.cpp with 83% similarity]
dali/internal/event/events/tap-gesture-event.h [moved from dali/integration-api/events/tap-gesture-event.h with 85% similarity]
dali/internal/event/events/tap-gesture-processor.cpp
dali/internal/event/events/tap-gesture-processor.h
dali/internal/event/events/tap-gesture-recognizer.cpp [new file with mode: 0644]
dali/internal/event/events/tap-gesture-recognizer.h [new file with mode: 0644]
dali/internal/file.list
dali/public-api/events/tap-gesture-detector.h

index 2566323..92da36c 100644 (file)
@@ -20,7 +20,6 @@ LIST(APPEND TC_SOURCES
         ../dali/dali-test-suite-utils/test-actor-utils.cpp
         ../dali/dali-test-suite-utils/dali-test-suite-utils.cpp
         ../dali/dali-test-suite-utils/test-application.cpp
-        ../dali/dali-test-suite-utils/test-gesture-manager.cpp
         ../dali/dali-test-suite-utils/test-gl-abstraction.cpp
         ../dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp
         ../dali/dali-test-suite-utils/test-native-image.cpp
index 62bad22..8267394 100644 (file)
@@ -46,6 +46,7 @@ SET(TC_SOURCES
         utc-Dali-LocklessBuffer.cpp
         utc-Dali-LongPressGesture.cpp
         utc-Dali-LongPressGestureDetector.cpp
+        utc-Dali-LongPressGestureRecognizer.cpp
         utc-Dali-MathUtils.cpp
         utc-Dali-Matrix.cpp
         utc-Dali-Matrix3.cpp
@@ -56,9 +57,11 @@ SET(TC_SOURCES
         utc-Dali-ObjectRegistry.cpp
         utc-Dali-PanGesture.cpp
         utc-Dali-PanGestureDetector.cpp
+        utc-Dali-PanGestureRecognizer.cpp
         utc-Dali-Path.cpp
         utc-Dali-PinchGesture.cpp
         utc-Dali-PinchGestureDetector.cpp
+        utc-Dali-PinchGestureRecognizer.cpp
         utc-Dali-Pixel.cpp
         utc-Dali-PixelData.cpp
         utc-Dali-Processors.cpp
@@ -86,6 +89,7 @@ SET(TC_SOURCES
         utc-Dali-Stage.cpp
         utc-Dali-TapGesture.cpp
         utc-Dali-TapGestureDetector.cpp
+        utc-Dali-TapGestureRecognizer.cpp
         utc-Dali-Texture.cpp
         utc-Dali-TextureSet.cpp
         utc-Dali-Thread.cpp
@@ -110,7 +114,7 @@ LIST(APPEND TC_SOURCES
         dali-test-suite-utils/test-custom-actor.cpp
         dali-test-suite-utils/test-harness.cpp
         dali-test-suite-utils/test-application.cpp
-        dali-test-suite-utils/test-gesture-manager.cpp
+        dali-test-suite-utils/test-gesture-generator.cpp
         dali-test-suite-utils/test-gl-abstraction.cpp
         dali-test-suite-utils/test-gl-sync-abstraction.cpp
         dali-test-suite-utils/test-native-image.cpp
index 70f4254..577ca36 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TEST_SUITE_UTILS_H__
-#define __DALI_TEST_SUITE_UTILS_H__
+#ifndef DALI_TEST_SUITE_UTILS_H
+#define DALI_TEST_SUITE_UTILS_H
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ void tet_printf(const char *format, ...);
 
 #include "test-application.h"
 #include "test-actor-utils.h"
+#include "test-gesture-generator.h"
 
 using namespace Dali;
 
@@ -442,4 +443,4 @@ private:
 
 } // namespace Test
 
-#endif // __DALI_TEST_SUITE_UTILS_H__
+#endif // DALI_TEST_SUITE_UTILS_H
index 1562d27..0b98b27 100644 (file)
@@ -47,7 +47,6 @@ void TestApplication::Initialize()
                                         mPlatformAbstraction,
                                         mGlAbstraction,
                                         mGlSyncAbstraction,
-                                        mGestureManager,
                                         mDataRetentionPolicy,
                                         Integration::RenderToFrameBuffer::FALSE,
                                         Integration::DepthBufferAvailable::TRUE,
@@ -141,11 +140,6 @@ TestGlSyncAbstraction& TestApplication::GetGlSyncAbstraction()
   return mGlSyncAbstraction;
 }
 
-TestGestureManager& TestApplication::GetGestureManager()
-{
-  return mGestureManager;
-}
-
 void TestApplication::ProcessEvent(const Integration::Event& event)
 {
   mCore->QueueEvent(event);
index fc2929c..27aafd3 100644 (file)
@@ -20,7 +20,6 @@
 
 // INTERNAL INCLUDES
 #include <test-platform-abstraction.h>
-#include "test-gesture-manager.h"
 #include "test-gl-sync-abstraction.h"
 #include "test-gl-abstraction.h"
 #include "test-render-controller.h"
@@ -68,7 +67,6 @@ public:
   TestRenderController& GetRenderController();
   TestGlAbstraction& GetGlAbstraction();
   TestGlSyncAbstraction& GetGlSyncAbstraction();
-  TestGestureManager& GetGestureManager();
   void ProcessEvent(const Integration::Event& event);
   void SendNotification();
   bool Render( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL, const char* location=NULL );
@@ -96,7 +94,6 @@ protected:
   TestRenderController      mRenderController;
   TestGlAbstraction         mGlAbstraction;
   TestGlSyncAbstraction     mGlSyncAbstraction;
-  TestGestureManager        mGestureManager;
   TestRenderSurface*        mRenderSurface;
 
   Integration::UpdateStatus mStatus;
diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gesture-generator.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-gesture-generator.cpp
new file mode 100644 (file)
index 0000000..a0ac206
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test-gesture-generator.h"
+
+// INTERNAL INCLUDES
+#include <dali/integration-api/events/touch-event-integ.h>
+
+namespace
+{
+const uint32_t RENDER_FRAME_INTERVAL = 16;                           ///< Duration of each frame in ms. (at approx 60FPS)
+
+Integration::TouchEvent GenerateSingleTouch( PointState::Type state, const Vector2& screenPosition, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( state );
+  point.SetDeviceId(4);
+  point.SetScreenPosition( screenPosition );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+Integration::TouchEvent GenerateDoubleTouch( PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( stateA );
+  point.SetDeviceId(4);
+  point.SetScreenPosition( screenPositionA );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  point.SetScreenPosition( screenPositionB );
+  point.SetState( stateB);
+  point.SetDeviceId(7);
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+} // namespace
+
+namespace Dali
+{
+uint32_t TestGetFrameInterval()
+{
+  return RENDER_FRAME_INTERVAL;
+}
+
+void TestStartLongPress( TestApplication& application, float x, float y, uint32_t time )
+{
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( x, y ), time ) );
+}
+
+void TestTriggerLongPress( TestApplication& application )
+{
+  application.GetPlatform().TriggerTimer();
+}
+
+void TestGenerateLongPress( TestApplication& application, float x, float y, uint32_t time )
+{
+  TestStartLongPress( application, x, y, time );
+  TestTriggerLongPress( application );
+}
+
+void TestEndLongPress( TestApplication& application, float x, float y, uint32_t time )
+{
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( x, y ), time ) );
+}
+
+void TestGeneratePinch( TestApplication& application)
+{
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 28.0f ), PointState::MOTION, Vector2( 20.0f, 82.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 37.0f ), PointState::MOTION, Vector2( 20.0f, 74.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 46.0f ), PointState::MOTION, Vector2( 20.0f, 66.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 58.0f ), 190 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::UP, Vector2( 20.0f, 55.0f ), PointState::UP, Vector2( 20.0f, 58.0f ), 200 ) );
+}
+
+void TestStartPinch( TestApplication& application, Vector2 a1, Vector2 b1, Vector2 a2, Vector2 b2, uint32_t time )
+{
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, a1, PointState::DOWN, b1, time ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, a2, PointState::MOTION, b2, time + 50 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, a2, PointState::MOTION, b2, time + 100 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, a2, PointState::MOTION, b2, time + 150 ) );
+}
+
+void TestContinuePinch( TestApplication& application, Vector2 a1, Vector2 b1, Vector2 a2, Vector2 b2, uint32_t time )
+{
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, a1, PointState::MOTION, b1, time ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, a1, PointState::MOTION, b1, time + 50 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, a2, PointState::MOTION, b2, time + 100 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, a2, PointState::MOTION, b2, time +150 ) );
+}
+
+void TestEndPinch( TestApplication& application, Vector2 a1, Vector2 b1, Vector2 a2, Vector2 b2, uint32_t time )
+{
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, a1, PointState::MOTION, b1, time ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::UP, a2, PointState::UP, b2, time +50 ) );
+}
+
+void TestGenerateMiniPan( TestApplication& application)
+{
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 250 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 251 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 40.0f ), 255 ) );
+}
+
+void TestStartPan( TestApplication& application, Vector2 start, Vector2 end, uint32_t& time )
+{
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, start, time ) );
+
+  time += RENDER_FRAME_INTERVAL;
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, end, time ) );
+
+  time += RENDER_FRAME_INTERVAL;
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, end, time ) );
+
+  time += RENDER_FRAME_INTERVAL;
+}
+
+void TestMovePan( TestApplication& application, Vector2 pos, uint32_t time )
+{
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, pos, time ) );
+}
+
+void TestEndPan( TestApplication& application, Vector2 pos, uint32_t time )
+{
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, pos, time ) );
+}
+
+void TestGenerateTap( TestApplication& application, float x, float y, uint32_t time_down )
+{
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( x, y ), time_down ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( x, y ), time_down + 20 ) );
+}
+
+void TestGenerateTwoPointTap( TestApplication& application, float x1, float y1, float x2, float y2, uint32_t time_down )
+{
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( x1, y1 ), PointState::DOWN, Vector2( x2, y2 ), time_down ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::UP, Vector2( x1, y1 ), PointState::UP, Vector2( x2, y2 ), time_down + 20 ) );
+}
+
+} // namespace Dali
diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gesture-generator.h b/automated-tests/src/dali/dali-test-suite-utils/test-gesture-generator.h
new file mode 100644 (file)
index 0000000..80611a0
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef DALI_TEST_GESTURE_GENERATOR_H
+#define DALI_TEST_GESTURE_GENERATOR_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test-application.h"
+
+namespace Dali
+{
+/**
+ * These functions use touch events to trigger a gesture, assuming the default gesture parameters are used
+ */
+
+/**
+ * Returns the frame interval used in ms
+ */
+uint32_t TestGetFrameInterval();
+
+/**
+ * Produces the initial touch of a long press
+ */
+void TestStartLongPress( TestApplication& application, float x = 20.0f, float y = 20.0f, uint32_t time = 450 );
+
+/**
+ * Triggers the timer to begin a long press gesture
+ */
+void TestTriggerLongPress( TestApplication& application );
+
+/**
+ * Produces the initial press and triggers the timer to begin a long press gesture
+ */
+void TestGenerateLongPress( TestApplication& application, float x = 20.0f, float y = 20.0f, uint32_t time = 450 );
+
+/**
+ * End a long press by lifting the touch
+ */
+void TestEndLongPress( TestApplication& application, float x = 20.0f, float y = 20.0f, uint32_t time = 450 );
+
+/**
+ * Produces a vertical pinch gesture between (20,20) and (20,90)
+ */
+void TestGeneratePinch( TestApplication& application );
+
+/**
+ * Produces the gesture started event of a pinch, using 4 touches, 50ms apart, starting with 1, ending at 2
+ */
+void TestStartPinch( TestApplication& application, Vector2 a1, Vector2 b1, Vector2 a2, Vector2 b2, uint32_t time );
+
+/**
+ * Produces a gesture continuing event of a pinch, using 4 touches, 50ms apart, starting with 1, ending at 2
+ */
+void TestContinuePinch( TestApplication& application, Vector2 a1, Vector2 b1, Vector2 a2, Vector2 b2, uint32_t time );
+
+/**
+ * Produces a gesture finished event of a pinch, using 2 touches, 50ms apart
+ */
+void TestEndPinch( TestApplication& application, Vector2 a1, Vector2 b1, Vector2 a2, Vector2 b2, uint32_t time );
+
+/**
+ * Produces a pan gesture from (20,20) to (20,40)
+ */
+void TestGenerateMiniPan( TestApplication& application );
+
+/**
+ * Produces the start event of a pan gesture, assuming minimum distance moved between start and end is greater than 15
+ * in either direction or 11 in both (x&y). Time will be incremented using the standard frame interval per touch movement
+ */
+void TestStartPan( TestApplication& application, Vector2 start, Vector2 end, uint32_t& time );
+
+/**
+ * Continues a pan event by creating a single touch at pos.
+ * N.B This does not increment the time
+ */
+void TestMovePan( TestApplication& application, Vector2 pos, uint32_t time = 400);
+
+/**
+ * End a pan gesture at position pos
+ */
+void TestEndPan( TestApplication& application, Vector2 pos, uint32_t time = 500);
+
+/**
+ * Produces a single point tap gesture with a 20ms interval
+ */
+void TestGenerateTap( TestApplication& application, float x = 20.0f, float y = 20.0f, uint32_t time_down = 100 );
+
+/**
+ * Produce a tap gesture with two touch points and a 20ms interval
+ */
+void TestGenerateTwoPointTap( TestApplication& application, float x1, float y1, float x2, float y2, uint32_t time_down );
+
+} // namespace Dali
+
+#endif // DALI_TEST_GESTURE_GENERATOR_H
diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.cpp
deleted file mode 100644 (file)
index 2844ff1..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2014 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 "test-gesture-manager.h"
-
-namespace Dali
-{
-
-TestGestureManager::TestGestureManager()
-{
-  Initialize();
-}
-
-/**
- * Destructor
- */
-TestGestureManager::~TestGestureManager()
-{
-}
-
-/**
- * @copydoc Dali::Integration::GestureManager::Register(Gesture::Type)
- */
-void TestGestureManager::Register(const Integration::GestureRequest& request)
-{
-  mFunctionsCalled.Register = true;
-}
-
-/**
- * @copydoc Dali::Integration::GestureManager::Unregister(Gesture::Type)
- */
-void TestGestureManager::Unregister(const Integration::GestureRequest& request)
-{
-  mFunctionsCalled.Unregister = true;
-}
-
-/**
- * @copydoc Dali::Integration::GestureManager::Update(Gesture::Type)
- */
-void TestGestureManager::Update(const Integration::GestureRequest& request)
-{
-  mFunctionsCalled.Update = true;
-}
-
-
-/** Call this every test */
-void TestGestureManager::Initialize()
-{
-  mFunctionsCalled.Reset();
-}
-
-bool TestGestureManager::WasCalled(TestFuncEnum func)
-{
-  switch(func)
-  {
-    case RegisterType:             return mFunctionsCalled.Register;
-    case UnregisterType:           return mFunctionsCalled.Unregister;
-    case UpdateType:               return mFunctionsCalled.Update;
-  }
-  return false;
-}
-
-void TestGestureManager::ResetCallStatistics(TestFuncEnum func)
-{
-  switch(func)
-  {
-    case RegisterType:             mFunctionsCalled.Register = false; break;
-    case UnregisterType:           mFunctionsCalled.Unregister = false; break;
-    case UpdateType:               mFunctionsCalled.Update = false; break;
-  }
-}
-
-TestGestureManager::TestFunctions::TestFunctions()
-: Register(false),
-  Unregister(false),
-  Update(false)
-{
-}
-
-void TestGestureManager::TestFunctions::Reset()
-{
-  Register = false;
-  Unregister = false;
-  Update = false;
-}
-
-
-
-} // namespace Dali
diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.h b/automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.h
deleted file mode 100644 (file)
index 6fddd30..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef __DALI_TEST_GESTURE_MANAGER_H__
-#define __DALI_TEST_GESTURE_MANAGER_H__
-
-/*
- * Copyright (c) 2018 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/integration-api/gesture-manager.h>
-#include <dali/public-api/common/dali-common.h>
-
-namespace Dali
-{
-
-/**
- * Concrete implementation of the gesture manager class.
- */
-class DALI_CORE_API TestGestureManager : public Dali::Integration::GestureManager
-{
-
-public:
-
-  /**
-   * Constructor
-   */
-  TestGestureManager();
-
-  /**
-   * Destructor
-   */
-  virtual ~TestGestureManager();
-
-  /**
-   * @copydoc Dali::Integration::GestureManager::Register(Gesture::Type)
-   */
-  virtual void Register(const Integration::GestureRequest& request);
-
-  /**
-   * @copydoc Dali::Integration::GestureManager::Unregister(Gesture::Type)
-   */
-  virtual void Unregister(const Integration::GestureRequest& request);
-
-  /**
-   * @copydoc Dali::Integration::GestureManager::Update(Gesture::Type)
-   */
-  virtual void Update(const Integration::GestureRequest& request);
-
-public: // TEST FUNCTIONS
-
-  // Enumeration of Gesture Manager methods
-  enum TestFuncEnum
-  {
-    RegisterType,
-    UnregisterType,
-    UpdateType,
-  };
-
-  /** Call this every test */
-  void Initialize();
-  bool WasCalled(TestFuncEnum func);
-  void ResetCallStatistics(TestFuncEnum func);
-
-private:
-
-  struct TestFunctions
-  {
-    TestFunctions();
-    void Reset();
-
-    bool Register;
-    bool Unregister;
-    bool Update;
-  };
-
-  TestFunctions mFunctionsCalled;
-};
-
-} // Dali
-
-#endif // __DALI_TEST_GESTURE_MANAGER_H__
index 190aa63..3962870 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,7 +28,9 @@ TestPlatformAbstraction::TestPlatformAbstraction()
   mClosestSize(),
   mLoadFileResult(),
   mSaveFileResult( false ),
-  mSynchronouslyLoadedResource()
+  mSynchronouslyLoadedResource(),
+  mTimerId(0),
+  mCallbackFunction(nullptr)
 {
   Initialize();
 }
@@ -82,7 +84,6 @@ bool TestPlatformAbstraction::LoadShaderBinaryFile( const std::string& filename,
   return mLoadFileResult.loadResult;
 }
 
-
 /** Call this every test */
 void TestPlatformAbstraction::Initialize()
 {
@@ -144,4 +145,24 @@ void TestPlatformAbstraction::SetDecodedBitmap( Integration::BitmapPtr bitmap )
   mDecodedBitmap = bitmap;
 }
 
+uint32_t TestPlatformAbstraction::StartTimer( uint32_t milliseconds, CallbackBase* callback )
+{
+  mCallbackFunction = callback;
+  mTimerId++;
+  return mTimerId;
+}
+
+void TestPlatformAbstraction::TriggerTimer()
+{
+  if (mCallbackFunction != nullptr)
+  {
+    CallbackBase::Execute( *mCallbackFunction );
+  }
+}
+
+void TestPlatformAbstraction::CancelTimer ( uint32_t timerId )
+{
+  mCallbackFunction = nullptr;
+}
+
 } // namespace Dali
index dfa4d6c..7c1b010 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TEST_PLATFORM_ABSTRACTION_H__
-#define __DALI_TEST_PLATFORM_ABSTRACTION_H__
+#ifndef DALI_TEST_PLATFORM_ABSTRACTION_H
+#define DALI_TEST_PLATFORM_ABSTRACTION_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -89,6 +89,15 @@ public:
    */
   virtual bool SaveShaderBinaryFile( const std::string& filename, const unsigned char * buffer, unsigned int numBytes ) const { return true; }
 
+  /**
+   * @copydoc PlatformAbstraction::StartTimer()
+   */
+  virtual uint32_t StartTimer( uint32_t milliseconds, CallbackBase* callback );
+
+  /*
+   * @copydoc PlatformAbstraction::CancelTimer()
+   */
+  virtual void CancelTimer ( uint32_t timerId );
 
 public: // TEST FUNCTIONS
 
@@ -156,6 +165,11 @@ public: // TEST FUNCTIONS
    */
   void SetDecodedBitmap( Integration::BitmapPtr bitmap );
 
+  /**
+   * @brief Triggers the previously stored callback function
+   */
+  void TriggerTimer();
+
 private:
 
   TestPlatformAbstraction( const TestPlatformAbstraction& ); ///< Undefined
@@ -184,8 +198,11 @@ private:
 
   Integration::ResourcePointer  mSynchronouslyLoadedResource;
   Integration::BitmapPtr        mDecodedBitmap;
+
+  uint32_t                      mTimerId;
+  CallbackBase*                 mCallbackFunction;
 };
 
 } // Dali
 
-#endif /* __DALI_TEST_PLATFORM_ABSTRACTION_H__ */
+#endif /* DALI_TEST_PLATFORM_ABSTRACTION_H */
index 1c81dc0..4ae9175 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -284,7 +284,6 @@ int UtcDaliGestureDetectorDetachN02(void)
 int UtcDaliGestureDetectorDetachN03(void)
 {
   TestApplication application;
-  TestGestureManager& gestureManager = application.GetGestureManager();
 
   // Use pan gesture as GestureDetector cannot be created.
   GestureDetector detector = PanGestureDetector::New();
@@ -292,21 +291,22 @@ int UtcDaliGestureDetectorDetachN03(void)
   Actor actor = Actor::New();
   detector.Attach(actor);
 
+  DALI_TEST_EQUALS(1, detector.GetAttachedActorCount(), TEST_LOCATION);
+
   // Detach an actor twice - no exception should happen.
   try
   {
     detector.Detach(actor);
-    DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-    gestureManager.Initialize(); // Reset values
     detector.Detach(actor);
-    DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
   }
   catch (DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
     tet_result(TET_FAIL);
   }
+
+  DALI_TEST_EQUALS(0, detector.GetAttachedActorCount(), TEST_LOCATION);
+
   END_TEST;
 }
 
@@ -339,7 +339,6 @@ int UtcDaliGestureDetectorDetachAllP(void)
 int UtcDaliGestureDetectorDetachAllN(void)
 {
   TestApplication application;
-  TestGestureManager& gestureManager = application.GetGestureManager();
 
   // Use pan gesture as GestureDetector cannot be created.
   GestureDetector detector = PanGestureDetector::New();
@@ -360,14 +359,11 @@ int UtcDaliGestureDetectorDetachAllN(void)
   detector.DetachAll();
 
   DALI_TEST_EQUALS(0u, detector.GetAttachedActorCount(), TEST_LOCATION);
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
 
   // Call DetachAll again, there should not be any exception
   try
   {
-    gestureManager.Initialize(); // Reset values
     detector.DetachAll();
-    DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
   }
   catch (DaliException& e)
   {
index d151a17..b7387f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
 #include <stdlib.h>
 #include <dali/public-api/dali-core.h>
 #include <dali/integration-api/events/touch-event-integ.h>
-#include <dali/integration-api/events/long-press-gesture-event.h>
 #include <dali/integration-api/render-task-list-integ.h>
 #include <dali-test-suite-utils.h>
 #include <test-touch-utils.h>
@@ -127,20 +126,6 @@ struct TouchEventFunctor
   }
 };
 
-// Generate a LongPressGestureEvent to send to Core
-Integration::LongPressGestureEvent GenerateLongPress(
-    Gesture::State state,
-    unsigned int numberOfTouches,
-    Vector2 point)
-{
-  Integration::LongPressGestureEvent longPress( state );
-
-  longPress.numberOfTouches = numberOfTouches;
-  longPress.point = point;
-
-  return longPress;
-}
-
 } // anon namespace
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -267,121 +252,6 @@ int UtcDaliLongPressGestureDetectorDownCast(void)
   END_TEST;
 }
 
-int UtcDaliLongPressGestureSetTouchesRequired01(void)
-{
-  TestApplication application;
-
-  LongPressGestureDetector detector = LongPressGestureDetector::New();
-
-  unsigned int touches = 3;
-
-  DALI_TEST_CHECK(touches != detector.GetMinimumTouchesRequired());
-  DALI_TEST_CHECK(touches != detector.GetMaximumTouchesRequired());
-
-  detector.SetTouchesRequired(touches);
-
-  DALI_TEST_EQUALS(touches, detector.GetMinimumTouchesRequired(), TEST_LOCATION);
-  DALI_TEST_EQUALS(touches, detector.GetMaximumTouchesRequired(), TEST_LOCATION);
-
-  // Attach an actor and change the required touches
-
-  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();
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect(&application, functor);
-
-  TestGestureManager& gestureManager = application.GetGestureManager();
-  gestureManager.Initialize();
-
-  detector.SetTouchesRequired(4);
-
-  // Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-  // Reset values
-  gestureManager.Initialize();
-
-  // Create a second gesture detector that requires even less maximum touches
-  LongPressGestureDetector secondDetector = LongPressGestureDetector::New();
-  secondDetector.Attach(actor);
-
-  // Gesture detection should have been updated
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-  END_TEST;
-}
-
-int UtcDaliLongPressGestureSetTouchesRequired02(void)
-{
-  TestApplication application;
-
-  LongPressGestureDetector detector = LongPressGestureDetector::New();
-
-  unsigned int min = 3;
-  unsigned int max = 5;
-
-  DALI_TEST_CHECK(min != detector.GetMinimumTouchesRequired());
-  DALI_TEST_CHECK(max != detector.GetMaximumTouchesRequired());
-
-  detector.SetTouchesRequired(min, max);
-
-  DALI_TEST_EQUALS(min, detector.GetMinimumTouchesRequired(), TEST_LOCATION);
-  DALI_TEST_EQUALS(max, detector.GetMaximumTouchesRequired(), TEST_LOCATION);
-
-  // Attach an actor and change the maximum touches
-
-  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();
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect(&application, functor);
-
-  TestGestureManager& gestureManager = application.GetGestureManager();
-  gestureManager.Initialize();
-
-  detector.SetTouchesRequired(4, 5);
-
-  // Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-  // Reset values
-  gestureManager.Initialize();
-
-  // Create a second gesture detector that requires even less maximum touches
-  LongPressGestureDetector secondDetector = LongPressGestureDetector::New();
-  secondDetector.Attach(actor);
-
-  // Gesture detection should have been updated
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-  END_TEST;
-}
-
 int UtcDaliLongPressGestureGetMinimumTouchesRequired(void)
 {
   TestApplication application;
@@ -421,9 +291,9 @@ int UtcDaliLongPressGestureSignalReceptionNegative(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do a long press outside actor's area
-  application.ProcessEvent( GenerateLongPress( Gesture::Possible, 1u, Vector2(112.0f, 112.0f ) ) );
-  application.ProcessEvent( GenerateLongPress( Gesture::Started,  1u, Vector2(112.0f, 112.0f ) ) );
-  application.ProcessEvent( GenerateLongPress( Gesture::Finished, 1u, Vector2(112.0f, 112.0f ) ) );
+  TestGenerateLongPress( application, 112.0f, 112.0f );
+  TestEndLongPress( application, 112.0f, 112.0f);
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -449,12 +319,11 @@ int UtcDaliLongPressGestureSignalReceptionPositive(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do a long press inside actor's area
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(50.0f, 50.0f)));
+  TestGenerateLongPress( application, 50.0f, 50.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
   DALI_TEST_EQUALS( Vector2(50.0f, 50.0f), data.receivedGesture.localPoint, 0.1, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished,  1u, Vector2(50.0f, 50.0f)));
+  TestEndLongPress( application, 50.0f, 50.0f);
   END_TEST;
 }
 
@@ -479,31 +348,28 @@ int UtcDaliLongPressGestureSignalReceptionDetach(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start long press within the actor's area
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(20.0f, 20.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(20.0f, 20.0f)));
+  TestGenerateLongPress( application, 20.0f, 20.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
   DALI_TEST_EQUALS( Vector2(20.0f, 20.0f), data.receivedGesture.localPoint, 0.1, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(20.0f, 20.0f)));
+  TestEndLongPress( application, 20.0f, 20.0f);
 
   // repeat the long press within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(50.0f, 50.0f)));
+  TestGenerateLongPress( application, 50.0f, 50.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
   DALI_TEST_EQUALS( Vector2(50.0f, 50.0f), data.receivedGesture.localPoint, 0.1, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 50.0f)));
+  TestEndLongPress( application, 50.0f, 50.0f);
 
   // Detach actor
   detector.DetachAll();
 
   // Ensure we are no longer signalled
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(20.0f, 20.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(20.0f, 20.0f)));
+  TestGenerateLongPress( application, 20.0f, 20.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 50.0f)));
+  TestEndLongPress( application, 50.0f, 50.0f);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -532,8 +398,7 @@ int UtcDaliLongPressGestureSignalReceptionActorDestroyedDuringLongPress(void)
     detector.Attach(actor);
 
     // Start long press within the actor's area
-    application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(20.0f, 20.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(20.0f, 20.0f)));
+    TestGenerateLongPress( application, 20.0f, 20.0f );
     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
     // Remove the actor from stage and reset the data
@@ -547,7 +412,7 @@ int UtcDaliLongPressGestureSignalReceptionActorDestroyedDuringLongPress(void)
   // Actor should now have been destroyed
 
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(20.0f, 20.0f)));
+  TestEndLongPress( application, 20.0f, 20.0f);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -573,9 +438,8 @@ int UtcDaliLongPressGestureSignalReceptionRotatedActor(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do a long press
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(5.0f, 5.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(5.0f, 5.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(5.0f, 5.0f)));
+  TestGenerateLongPress( application, 5.0f, 5.0f );
+  TestEndLongPress( application, 5.0f, 5.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
   DALI_TEST_EQUALS( Vector2(5.0f, 5.0f), data.receivedGesture.screenPoint, 0.1, TEST_LOCATION);
@@ -587,9 +451,8 @@ int UtcDaliLongPressGestureSignalReceptionRotatedActor(void)
 
   // Do another long press, should still receive event
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(5.0f, 5.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(5.0f, 5.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(5.0f, 5.0f)));
+  TestGenerateLongPress( application, 5.0f, 5.0f );
+  TestEndLongPress( application, 5.0f, 5.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
   DALI_TEST_EQUALS( Vector2(5.0f, 5.0f), data.receivedGesture.screenPoint, 0.1, TEST_LOCATION);
@@ -601,9 +464,8 @@ int UtcDaliLongPressGestureSignalReceptionRotatedActor(void)
 
   // Do a long press, inside where the actor used to be, Should not receive the event
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(70.0f, 70.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(70.0f, 70.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(70.0f, 70.0f)));
+  TestGenerateLongPress( application, 70.0f, 70.0f );
+  TestEndLongPress( application, 70.0f, 70.0f);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -642,9 +504,8 @@ int UtcDaliLongPressGestureSignalReceptionChildHit(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do long press - hits child area but parent should still receive it
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 50.0f)));
+  TestGenerateLongPress( application, 50.0f, 50.0f );
+  TestEndLongPress( application, 50.0f, 50.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, parent == data.pressedActor, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.screenPoint, 0.01f, TEST_LOCATION);
@@ -656,9 +517,8 @@ int UtcDaliLongPressGestureSignalReceptionChildHit(void)
 
   // Do an entire long press, only check finished value
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(51.0f, 51.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(51.0f, 51.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(51.0f, 51.0f)));
+  TestGenerateLongPress( application, 51.0f, 51.0f );
+  TestEndLongPress( application, 51.0f, 51.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, child == data.pressedActor, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(51.0f, 51.0f), data.receivedGesture.screenPoint, 0.01f, TEST_LOCATION);
@@ -693,17 +553,15 @@ int UtcDaliLongPressGestureSignalReceptionAttachDetachMany(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // LongPress within second actor's area
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(120.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(120.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(120.0f, 10.0f)));
+  TestGenerateLongPress( application, 120.0f, 10.0f );
+  TestEndLongPress( application, 120.0f, 10.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, second == data.pressedActor, TEST_LOCATION);
 
   // LongPress within first actor's area
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(20.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(20.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(20.0f, 10.0f)));
+  TestGenerateLongPress( application, 20.0f, 10.0f );
+  TestEndLongPress( application, 20.0f, 10.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, first == data.pressedActor, TEST_LOCATION);
 
@@ -712,16 +570,14 @@ int UtcDaliLongPressGestureSignalReceptionAttachDetachMany(void)
 
   // second actor shouldn't receive event
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(120.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(120.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(120.0f, 10.0f)));
+  TestGenerateLongPress( application, 120.0f, 10.0f );
+  TestEndLongPress( application, 120.0f, 10.0f);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // first actor should continue receiving event
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(20.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(20.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(20.0f, 10.0f)));
+  TestGenerateLongPress( application, 20.0f, 10.0f );
+  TestEndLongPress( application, 20.0f, 10.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -747,9 +603,8 @@ int UtcDaliLongPressGestureSignalReceptionActorBecomesUntouchable(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // LongPress in actor's area
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
+  TestEndLongPress( application, 50.0f, 10.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Actor becomes invisible - actor should not receive the next long press
@@ -761,94 +616,12 @@ int UtcDaliLongPressGestureSignalReceptionActorBecomesUntouchable(void)
 
   // LongPress in the same area, shouldn't receive event
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
+  TestEndLongPress( application, 50.0f, 10.0f);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliLongPressGestureSignalReceptionMultipleGestureDetectors(void)
-{
-  TestApplication application;
-  Dali::TestGestureManager& gestureManager = application.GetGestureManager();
-
-  Actor first = Actor::New();
-  first.SetSize(100.0f, 100.0f);
-  first.SetAnchorPoint(AnchorPoint::TOP_LEFT);
-  Stage::GetCurrent().Add(first);
-
-  Actor second = Actor::New();
-  second.SetSize(100.0f, 100.0f);
-  second.SetAnchorPoint(AnchorPoint::TOP_LEFT);
-  second.SetX(100.0f);
-  first.Add(second);
-
-  // Render and notify
-  application.SendNotification();
-  application.Render();
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  LongPressGestureDetector firstDetector = LongPressGestureDetector::New();
-  firstDetector.Attach(first);
-  firstDetector.DetectedSignal().Connect(&application, functor);
-
-  // secondDetector is scoped
-  {
-    // Reset gestureManager statistics
-    gestureManager.Initialize();
-
-    LongPressGestureDetector secondDetector = LongPressGestureDetector::New();
-    secondDetector.SetTouchesRequired(2);
-    secondDetector.Attach(second);
-    secondDetector.DetectedSignal().Connect(&application, functor);
-
-    DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-    DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-    DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-    // LongPress within second actor's area
-    application.ProcessEvent(GenerateLongPress(Gesture::Possible, 2u, Vector2(150.0f, 10.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Started,  2u, Vector2(150.0f, 10.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Finished, 2u, Vector2(150.0f, 10.0f)));
-    DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-    DALI_TEST_EQUALS(true, second == data.pressedActor, TEST_LOCATION);
-
-    // LongPress continues as single touch gesture - we should not receive any gesture
-    data.Reset();
-    application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(150.0f, 10.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(150.0f, 10.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(150.0f, 10.0f)));
-    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-    // Single touch long press starts - first actor should receive gesture
-    data.Reset();
-    application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Started,  1u, Vector2(50.0f, 10.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
-    DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-    DALI_TEST_EQUALS(true, first == data.pressedActor, TEST_LOCATION);
-
-    // long press changes to double-touch - we shouldn't receive event
-    data.Reset();
-    application.ProcessEvent(GenerateLongPress(Gesture::Possible, 2u, Vector2(50.0f, 10.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Started, 2u, Vector2(50.0f, 10.0f)));
-    application.ProcessEvent(GenerateLongPress(Gesture::Finished, 2u, Vector2(50.0f, 10.0f)));
-    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-    // Reset gesture manager statistics
-    gestureManager.Initialize();
-  }
-
-  // secondDetector has now been deleted.  Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-  END_TEST;
-}
-
 int UtcDaliLongPressGestureSignalReceptionMultipleDetectorsOnActor(void)
 {
   TestApplication application;
@@ -877,8 +650,7 @@ int UtcDaliLongPressGestureSignalReceptionMultipleDetectorsOnActor(void)
   secondDetector.DetectedSignal().Connect(&application, secondFunctor);
 
   // LongPress in actor's area - both detector's functors should be called
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
   END_TEST;
@@ -905,7 +677,7 @@ int UtcDaliLongPressGestureSignalReceptionDifferentPossible(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // LongPress possible in actor's area.
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
+  TestStartLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Move actor somewhere else
@@ -916,12 +688,12 @@ int UtcDaliLongPressGestureSignalReceptionDifferentPossible(void)
   application.Render();
 
   // Emit Started event, we should not receive the long press.
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestTriggerLongPress( application );
+  TestGenerateLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // LongPress possible in empty area.
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
+  TestStartLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Move actor in to the long press position.
@@ -932,137 +704,17 @@ int UtcDaliLongPressGestureSignalReceptionDifferentPossible(void)
   application.Render();
 
   // Emit Started event, we should not receive the long press.
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestTriggerLongPress( application );
+  TestEndLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Normal long press in actor's area for completeness.
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
+  TestEndLongPress( application, 50.0f, 10.0f);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliLongPressGestureEmitIncorrectStateClear(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  LongPressGestureDetector detector = LongPressGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Try a Clear state
-  try
-  {
-    application.ProcessEvent(GenerateLongPress(Gesture::Clear, 1u, Vector2(50.0f, 10.0f)));
-    tet_result(TET_FAIL);
-  }
-  catch ( Dali::DaliException& e )
-  {
-    DALI_TEST_ASSERT( e, "Incorrect state", TEST_LOCATION );
-  }
-  END_TEST;
-}
-
-int UtcDaliLongPressGestureEmitIncorrectStateContinuing(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  LongPressGestureDetector detector = LongPressGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Try a Continuing state
-  try
-  {
-    application.ProcessEvent(GenerateLongPress(Gesture::Continuing, 1u, Vector2(50.0f, 10.0f)));
-    tet_result(TET_FAIL);
-  }
-  catch ( Dali::DaliException& e )
-  {
-    DALI_TEST_ASSERT( e, "Incorrect state", TEST_LOCATION );
-  }
-  END_TEST;
-}
-
-int UtcDaliLongPressGestureRepeatedState(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  LongPressGestureDetector detector = LongPressGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Two possibles
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-  // ... Send some finished states, still no signal
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-  // Send two Started states, should be signalled
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  data.Reset();
-
-  // Send two cancelled states, should not be signalled
-  application.ProcessEvent(GenerateLongPress(Gesture::Cancelled, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Cancelled, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  END_TEST;
-}
-
 int UtcDaliLongPressGesturePossibleCancelled(void)
 {
   TestApplication application;
@@ -1084,9 +736,9 @@ int UtcDaliLongPressGesturePossibleCancelled(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Send a possible followed by a cancel, we should not be signalled
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
+  TestStartLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  application.ProcessEvent(GenerateLongPress(Gesture::Cancelled, 1u, Vector2(50.0f, 10.0f)));
+  TestMovePan( application, Vector2( 50.0f, 10.0f ) );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -1112,8 +764,7 @@ int UtcDaliLongPressGestureDetachAfterStarted(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Emit initial signal
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1121,7 +772,7 @@ int UtcDaliLongPressGestureDetachAfterStarted(void)
   detector.Detach(actor);
 
   // Emit Finished, no signal
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestEndLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -1150,11 +801,10 @@ int UtcDaliLongPressGestureActorUnstaged(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Emit signals
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestEndLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Render and notify
@@ -1172,11 +822,10 @@ int UtcDaliLongPressGestureActorUnstaged(void)
   stateToUnstage = Gesture::Finished;
 
   // Emit signals
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestEndLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   tet_result( TET_PASS ); // If we get here then we have handled actor stage removal gracefully.
   END_TEST;
@@ -1218,8 +867,7 @@ int UtcDaliLongPressGestureActorStagedAndDestroyed(void)
   // position, we should still not be signalled.
 
   // Emit signals
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1235,15 +883,14 @@ int UtcDaliLongPressGestureActorStagedAndDestroyed(void)
   application.Render();
 
   // Continue signal emission
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestEndLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
   // Here we delete an actor in started, we should not receive any subsequent signalling.
 
   // Emit signals
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1259,7 +906,7 @@ int UtcDaliLongPressGestureActorStagedAndDestroyed(void)
   application.Render();
 
   // Continue signal emission
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestEndLongPress( application, 50.0f, 10.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -1291,12 +938,9 @@ int UtcDaliLongPressGestureLayerConsumesTouch(void)
   application.SendNotification();
   application.Render();
 
-  Vector2 screenCoords( 50.0f, 50.0f );
-
   // Emit signals, should receive
-  application.ProcessEvent( GenerateLongPress( Gesture::Possible, 1u, screenCoords ) );
-  application.ProcessEvent( GenerateLongPress( Gesture::Started, 1u, screenCoords ) );
-  application.ProcessEvent( GenerateLongPress( Gesture::Finished, 1u, screenCoords ) );
+  TestGenerateLongPress( application, 50.0f, 50.0f );
+  TestEndLongPress( application, 50.0f, 50.0f );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1308,9 +952,8 @@ int UtcDaliLongPressGestureLayerConsumesTouch(void)
   application.Render();
 
   // Emit the same signals again, should not receive
-  application.ProcessEvent( GenerateLongPress( Gesture::Possible, 1u, screenCoords ) );
-  application.ProcessEvent( GenerateLongPress( Gesture::Started, 1u, screenCoords ) );
-  application.ProcessEvent( GenerateLongPress( Gesture::Finished, 1u, screenCoords ) );
+  TestGenerateLongPress( application, 50.0f, 50.0f );
+  TestEndLongPress( application, 50.0f, 50.0f );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
diff --git a/automated-tests/src/dali/utc-Dali-LongPressGestureRecognizer.cpp b/automated-tests/src/dali/utc-Dali-LongPressGestureRecognizer.cpp
new file mode 100644 (file)
index 0000000..e5ec64b
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <thread>
+#include <chrono>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/long-press-gesture-event.h>
+#include <dali-test-suite-utils.h>
+#include <test-touch-utils.h>
+
+using namespace Dali;
+
+///////////////////////////////////////////////////////////////////////////////
+namespace
+{
+
+struct SignalData
+{
+  SignalData()
+  : functorCalled(false),
+    voidFunctorCalled(false),
+    receivedGesture(Gesture::Started)
+  {}
+
+  void Reset()
+  {
+    functorCalled = false;
+    voidFunctorCalled = false;
+
+    receivedGesture.state = Gesture::Started;
+
+    pressedActor.Reset();
+  }
+
+  bool functorCalled;
+  bool voidFunctorCalled;
+  LongPressGesture receivedGesture;
+  Actor pressedActor;
+};
+
+// Functor that sets the data when called
+struct GestureReceivedFunctor
+{
+  GestureReceivedFunctor(SignalData& data) : signalData(data) { }
+
+  void operator()(Actor actor, const LongPressGesture& pan)
+  {
+    signalData.functorCalled = true;
+    signalData.receivedGesture = pan;
+    signalData.pressedActor = actor;
+  }
+
+  void operator()()
+  {
+    signalData.voidFunctorCalled = true;
+  }
+
+  SignalData& signalData;
+};
+
+
+Integration::TouchEvent GenerateSingleTouch( PointState::Type state, const Vector2& screenPosition, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( state );
+  point.SetDeviceId(4);
+  point.SetScreenPosition( screenPosition );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+Integration::TouchEvent GenerateDoubleTouch( PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( stateA );
+  point.SetDeviceId(4);
+  point.SetScreenPosition( screenPositionA );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  point.SetScreenPosition( screenPositionB );
+  point.SetState( stateB);
+  point.SetDeviceId(7);
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+
+} // anon namespace
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+int UtcDaliLongPressGestureRecognizerBasicNoAction(void)
+{
+  TestApplication application;
+
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLongPressGestureRecognizerBasic(void)
+{
+  TestApplication application;
+
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.GetPlatform().TriggerTimer();
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLongPressGestureRecognizerTooShortWait(void)
+{
+  TestApplication application;
+
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLongPressGestureRecognizerTooFewPoints(void)
+{
+  TestApplication application;
+
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+
+  detector.SetTouchesRequired(2,2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  // There should be no function to call
+  application.GetPlatform().TriggerTimer();
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLongPressGestureRecognizerTooManyPoints(void)
+{
+  TestApplication application;
+
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 151 ) );
+
+  // There should be no function to call as the double touch should have cancelled it
+  application.GetPlatform().TriggerTimer();
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLongPressGestureRecognizerMultiplePointsMoving(void)
+{
+  TestApplication application;
+
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+
+  detector.SetTouchesRequired(2,2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 0.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 151 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 10.0f ), PointState::MOTION, Vector2( 20.0f, 80.0f ), 153 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 20.0f, 70.0f ), 155 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 30.0f ), PointState::MOTION, Vector2( 20.0f, 60.0f ), 157 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), PointState::MOTION, Vector2( 20.0f, 50.0f ), 159 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::STATIONARY, Vector2( 20.0f, 40.0f ), PointState::UP, Vector2( 20.0f, 50.0f ), 160 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 40.0f ), 161 ) );
+
+  application.GetPlatform().TriggerTimer();
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLongPressGestureRecognizerMultiplePointsLongPress(void)
+{
+  TestApplication application;
+
+  LongPressGestureDetector detector = LongPressGestureDetector::New();
+
+  detector.SetTouchesRequired(2,2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 40.0f ), 140 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 40.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+
+  application.GetPlatform().TriggerTimer();
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::STATIONARY, Vector2( 20.0f, 20.0f ), PointState::UP, Vector2( 20.0f, 90.0f ), 760 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 761 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLongPressGestureRecognizerMultipleDetectors(void)
+{
+  TestApplication application;
+
+    Actor actor = Actor::New();
+    actor.SetSize(100.0f, 100.0f);
+    actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+    Stage::GetCurrent().Add(actor);
+
+    Actor actor2 = Actor::New();
+    actor2.SetSize(100.0f, 100.0f);
+    actor2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+    actor2.SetX(100.0f);
+    Stage::GetCurrent().Add(actor2);
+
+    // Render and notify
+    application.SendNotification();
+    application.Render();
+
+    LongPressGestureDetector detector = LongPressGestureDetector::New();
+    detector.Attach(actor);
+
+    LongPressGestureDetector detector2 = LongPressGestureDetector::New(2);
+    detector2.Attach(actor2);
+
+    SignalData data;
+    GestureReceivedFunctor functor(data);
+    detector.DetectedSignal().Connect(&application, functor);
+
+    SignalData data2;
+    GestureReceivedFunctor functor2(data2);
+    detector2.DetectedSignal().Connect(&application, functor2);
+
+    application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+    application.GetPlatform().TriggerTimer();
+
+    application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 700 ) );
+
+    application.SendNotification();
+
+    DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+    DALI_TEST_EQUALS(true, actor == data.pressedActor, TEST_LOCATION);
+    data.Reset();
+    DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
+
+    application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 120.0f, 40.0f ), 800 ) );
+    application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 120.0f, 40.0f ), PointState::DOWN, Vector2( 120.0f, 90.0f ), 805 ) );
+
+    application.GetPlatform().TriggerTimer();
+
+    application.SendNotification();
+
+    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+    DALI_TEST_EQUALS(true, data2.functorCalled, TEST_LOCATION);
+
+    END_TEST;
+}
index 0cbc64d..52976fb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <cmath>
 #include <dali/public-api/dali-core.h>
 #include <dali/integration-api/events/touch-event-integ.h>
-#include <dali/integration-api/events/pan-gesture-event.h>
 #include <dali/integration-api/render-task-list-integ.h>
 #include <dali/integration-api/profiling.h>
 #include <dali/integration-api/input-options.h>
+#include <dali/internal/event/events/pan-gesture-event.h>
 #include <dali-test-suite-utils.h>
 #include <test-touch-utils.h>
 
@@ -174,26 +174,6 @@ struct PanConstraint
   ConstraintData& constraintData;
 };
 
-// Generate a PanGestureEvent to send to Core
-Integration::PanGestureEvent GeneratePan(
-    Gesture::State state,
-    Vector2 previousPosition,
-    Vector2 currentPosition,
-    unsigned long timeDelta,
-    unsigned int numberOfTouches = 1,
-    unsigned int time = 1u)
-{
-  Integration::PanGestureEvent pan(state);
-
-  pan.previousPosition = previousPosition;
-  pan.currentPosition = currentPosition;
-  pan.timeDelta = timeDelta;
-  pan.numberOfTouches = numberOfTouches;
-  pan.time = time;
-
-  return pan;
-}
-
 // Generate a PanGesture
 PanGesture GeneratePan( unsigned int time,
                         Gesture::State state,
@@ -223,67 +203,6 @@ PanGesture GeneratePan( unsigned int time,
   return pan;
 }
 
-/**
- * Helper to generate PanGestureEvent
- *
- * @param[in] application Application instance
- * @param[in] state The Gesture State
- * @param[in] pos The current position of touch.
- */
-static void SendPan(TestApplication& application, Gesture::State state, const Vector2& pos)
-{
-  static Vector2 last;
-  static int LastTime = 0;
-
-  if( (state == Gesture::Started) ||
-      (state == Gesture::Possible) )
-  {
-    last.x = pos.x;
-    last.y = pos.y;
-  }
-
-  application.ProcessEvent(GeneratePan(state, last, pos, PAN_EVENT_TIME_DELTA));
-
-  last.x = pos.x;
-  last.y = pos.y;
-  LastTime += PAN_EVENT_TIME_DELTA;
-}
-
-static Vector2 PerformSwipeGestureSwipe(TestApplication& application, Vector2 startPosition, Vector2 direction, int frames, int eventsPerFrame,
-                                        bool start, bool finish, unsigned int renderInterval = TestApplication::DEFAULT_RENDER_INTERVAL)
-{
-  // Now do a pan starting from (start) and heading (direction)
-  Vector2 pos(startPosition);
-
-  if( start )
-  {
-    SendPan(application, Gesture::Possible, pos);
-    SendPan(application, Gesture::Started, pos);
-    application.SendNotification();
-    application.Render(renderInterval);
-  }
-
-  for(int i = 0;i<frames;i++)
-  {
-    for( int j = 0; j < eventsPerFrame; j++ )
-    {
-      pos += direction; // Move in this direction
-      SendPan(application, Gesture::Continuing, pos);
-    }
-    application.SendNotification();
-    application.Render(renderInterval);
-  }
-
-  if(finish)
-  {
-    SendPan(application, Gesture::Finished, pos);
-    application.SendNotification();
-    application.Render(renderInterval);
-  }
-
-  return pos;
-}
-
 } // anon namespace
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -347,13 +266,9 @@ int UtcDaliPanGestureDetectorNew(void)
   application.SendNotification();
   application.Render();
 
-  Integration::TouchEvent touchEvent(1);
-  Integration::Point point;
-  point.SetDeviceId( 1 );
-  point.SetState( PointState::DOWN );
-  point.SetScreenPosition( Vector2( 20.0f, 20.0f ) );
-  touchEvent.AddPoint(point);
-  application.ProcessEvent(touchEvent);
+  // Use long press function for touch event
+  TestStartLongPress( application );
+
   END_TEST;
 }
 
@@ -416,27 +331,14 @@ int UtcDaliPanGestureSetMinimumTouchesRequired(void)
   detector.Attach(actor);
   detector.DetectedSignal().Connect(&application, functor);
 
-  TestGestureManager& gestureManager = application.GetGestureManager();
-  gestureManager.Initialize();
-
   detector.SetMinimumTouchesRequired(3);
 
-  // Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-  // Reset values
-  gestureManager.Initialize();
-
   // Create a second gesture detector that requires even less minimum touches
   PanGestureDetector secondDetector = PanGestureDetector::New();
   secondDetector.Attach(actor);
 
-  // Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
+  DALI_TEST_EQUALS(3, detector.GetMinimumTouchesRequired(), TEST_LOCATION);
+
   END_TEST;
 }
 
@@ -471,27 +373,10 @@ int UtcDaliPanGestureSetMaximumTouchesRequired(void)
   detector.Attach(actor);
   detector.DetectedSignal().Connect(&application, functor);
 
-  TestGestureManager& gestureManager = application.GetGestureManager();
-  gestureManager.Initialize();
-
   detector.SetMaximumTouchesRequired(4);
 
-  // Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-  // Reset values
-  gestureManager.Initialize();
+  DALI_TEST_EQUALS(4, detector.GetMaximumTouchesRequired(), TEST_LOCATION);
 
-  // Create a second gesture detector that requires even less maximum touches
-  PanGestureDetector secondDetector = PanGestureDetector::New();
-  secondDetector.Attach(actor);
-
-  // Gesture detection should NOT have been updated
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
   END_TEST;
 }
 
@@ -534,18 +419,21 @@ int UtcDaliPanGestureSignalReceptionNegative(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do a pan outside actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(110.0f, 110.0f), Vector2(112.0f, 112.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(110.0f, 110.0f), Vector2(112.0f, 112.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2(110.0f, 110.0f), Vector2(121.0f, 121.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Continue pan into actor's area - we should still not receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(112.0f, 112.0f), Vector2(20.0f, 20.0f), 10));
+  TestMovePan( application, Vector2(20.0f, 20.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Stop panning - we should still not receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 20.0f), Vector2(12.0f, 12.0f), 10));
+  TestEndPan( application, Vector2(12.0f, 12.0f), time);
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -571,48 +459,57 @@ int UtcDaliPanGestureSignalReceptionDownMotionLeave(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pan within the actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(10.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(1.0f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(1.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(16.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(0.5f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(16.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.5f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
 
   // Continue the pan within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
+
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(0.0f, -10.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(0.0f, -16.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(0.0f, -1.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(16.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(1.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
 
   // Pan Gesture leaves actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 10.0f), Vector2(320.0f, 10.0f), 10));
+
+  TestMovePan( application, Vector2(346.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(300.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(30.0f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(300.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(30.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(320.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(20.0f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(320.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(20.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
 
   // Gesture ends - we would receive a finished state
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(320.0f, 10.0f), Vector2(310.0f, 10.0f), 10));
+
+  TestEndPan( application, Vector2(314.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Finished, data.receivedGesture.state, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(-10.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(-1.0f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(1.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(-32.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(-2.0f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(32.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(2.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
   END_TEST;
 }
 
@@ -637,41 +534,47 @@ int UtcDaliPanGestureSignalReceptionDownMotionUp(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pan within the actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(10.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(1.0f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(1.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(16.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(0.5f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(16.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.5f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
 
   // Continue the pan within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
+
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(0.0f, -10.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(0.0f, -16.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(0.0f, -1.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(16.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(1.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
 
   // Gesture ends within actor's area - we would receive a finished state
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 10.0f), Vector2(10.0f, 10.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Finished, data.receivedGesture.state, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(-10.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(-16.0f, 0.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(-1.0f, 0.0f), data.receivedGesture.velocity, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(16.0f, data.receivedGesture.GetDistance(), 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(1.0f, data.receivedGesture.GetSpeed(), 0.01f, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliPanGestureSignalReceptionCancelled(void)
+int UtcDaliPanGestureSignalReceptionDetach(void)
 {
   TestApplication application;
 
@@ -692,58 +595,24 @@ int UtcDaliPanGestureSignalReceptionCancelled(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pan within the actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
 
   // Continue the pan within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
 
-  // The gesture is cancelled
-  data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Cancelled, Vector2(20.0f, 10.0f), Vector2(10.0f, 10.0f), 10));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Gesture::Cancelled, data.receivedGesture.state, TEST_LOCATION);
-  END_TEST;
-}
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
 
-int UtcDaliPanGestureSignalReceptionDetach(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();
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  PanGestureDetector detector = PanGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect(&application, functor);
-
-  // Start pan within the actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-
-  // Continue the pan within the actor's area - we should still receive the signal
-  data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Gesture ends within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 10.0f), Vector2(10.0f, 10.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Detach actor
@@ -751,10 +620,12 @@ int UtcDaliPanGestureSignalReceptionDetach(void)
 
   // Ensure we are no longer signalled
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 10.0f), Vector2(10.0f, 10.0f), 10));
+
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -780,13 +651,18 @@ int UtcDaliPanGestureSignalReceptionDetachWhilePanning(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pan within the actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+  application.SendNotification();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Continue the pan within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
+
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Detach actor during the pan, we should not receive the next event
@@ -794,7 +670,9 @@ int UtcDaliPanGestureSignalReceptionDetachWhilePanning(void)
 
   // Gesture ends within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 10.0f), Vector2(10.0f, 10.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -817,6 +695,8 @@ int UtcDaliPanGestureSignalReceptionActorDestroyedWhilePanning(void)
   Stage::GetCurrent().Add(tempActor);
   detector.Attach(tempActor);
 
+  uint32_t time = 100;
+
   // Actor lifetime is scoped
   {
     Actor actor = Actor::New();
@@ -831,13 +711,16 @@ int UtcDaliPanGestureSignalReceptionActorDestroyedWhilePanning(void)
     detector.Attach(actor);
 
     // Start pan within the actor's area
-    application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-    application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+    TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
     // Continue the pan within the actor's area - we should still receive the signal
     data.Reset();
-    application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
+
+    TestMovePan( application, Vector2(26.0f, 4.0f), time );
+    time += TestGetFrameInterval();
+
     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
     // Remove the actor from stage and reset the data
@@ -852,7 +735,9 @@ int UtcDaliPanGestureSignalReceptionActorDestroyedWhilePanning(void)
 
   // Gesture ends within the area where the actor used to be
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 10.0f), Vector2(10.0f, 10.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -878,12 +763,15 @@ int UtcDaliPanGestureSignalReceptionRotatedActor(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do an entire pan, only check finished value
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 11.0f, 12.0f ),  Vector2( 27.0f, 12.0f ), time );
+
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(22.0f, 12.0f), Vector2(27.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(25.0f, 28.0f), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(8.0f, -5.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
+  DALI_TEST_EQUALS(Vector2(16.0f, 2.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
 
   // Rotate actor again and render a couple of times
   actor.SetOrientation(Dali::Degree(180.0f), Vector3::ZAXIS);
@@ -891,12 +779,14 @@ int UtcDaliPanGestureSignalReceptionRotatedActor(void)
   application.Render();
 
   // Do an entire pan, only check finished value
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
+  TestStartPan( application, Vector2( 11.0f, 12.0f ),  Vector2( 27.0f, 12.0f ), time );
+
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(22.0f, 12.0f), Vector2(27.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(25.0f, 28.0f), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(-5.0f, -8.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
+  DALI_TEST_EQUALS(Vector2(2.0f, -16.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
 
   // Rotate actor again and render a couple of times
   actor.SetOrientation(Dali::Degree(270.0f), Vector3::ZAXIS);
@@ -904,12 +794,14 @@ int UtcDaliPanGestureSignalReceptionRotatedActor(void)
   application.Render();
 
   // Do an entire pan, only check finished value
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
+  TestStartPan( application, Vector2( 11.0f, 12.0f ),  Vector2( 27.0f, 12.0f ), time );
+
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(22.0f, 12.0f), Vector2(27.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(25.0f, 28.0f), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(-8.0f, 5.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
+  DALI_TEST_EQUALS(Vector2(-16.0f, -2.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
   END_TEST;
 }
 
@@ -947,13 +839,16 @@ int UtcDaliPanGestureSignalReceptionChildHit(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do an entire pan, only check finished value - hits child area but parent should still receive it
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 11.0f, 12.0f ),  Vector2( 27.0f, 12.0f ), time );
+
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(22.0f, 12.0f), Vector2(27.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(25.0f, 28.0f), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, parent == data.pannedActor, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(5.0f, 8.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
+  DALI_TEST_EQUALS(Vector2(-2.0f, 16.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
 
   // Attach child and generate same touch points to yield a different displacement
   // (Also proves that you can detach and then re-attach another actor)
@@ -961,13 +856,15 @@ int UtcDaliPanGestureSignalReceptionChildHit(void)
   detector.Detach(parent);
 
   // Do an entire pan, only check finished value
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(11.0f, 12.0f), Vector2(22.0f, 12.0f), 10));
+  TestStartPan( application, Vector2( 11.0f, 12.0f ),  Vector2( 27.0f, 12.0f ), time );
+
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(22.0f, 12.0f), Vector2(27.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(25.0f, 28.0f), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, child == data.pannedActor, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(8.0f, -5.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
+  DALI_TEST_EQUALS(Vector2(16.0f, 2.0f), data.receivedGesture.displacement, 0.01f, TEST_LOCATION); // Actor relative
   END_TEST;
 }
 
@@ -998,15 +895,25 @@ int UtcDaliPanGestureSignalReceptionAttachDetachMany(void)
   detector.Attach(second);
   detector.DetectedSignal().Connect(&application, functor);
 
+  DALI_TEST_EQUALS(Stage::GetCurrent().GetRootLayer(), first.GetParent(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Stage::GetCurrent().GetRootLayer(), second.GetParent(), TEST_LOCATION);
+
   // Start pan within second actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(110.0f, 20.0f), Vector2(120.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(110.0f, 20.0f), Vector2(120.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 110.0f, 20.0f ),  Vector2( 126.0f, 20.0f ), time );
+
+  DALI_TEST_EQUALS(Stage::GetCurrent().GetRootLayer(), first.GetParent(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Stage::GetCurrent().GetRootLayer(), second.GetParent(), TEST_LOCATION);
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, second == data.pannedActor, TEST_LOCATION);
 
   // Pan moves into first actor's area - second actor should receive the pan
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(120.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
+
+  TestMovePan( application, Vector2(126.0f, 20.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, second == data.pannedActor, TEST_LOCATION);
 
@@ -1015,8 +922,12 @@ int UtcDaliPanGestureSignalReceptionAttachDetachMany(void)
 
   // Gesture ends within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 10.0f), Vector2(10.0f, 10.0f), 10));
+
+  TestMovePan( application, Vector2(26.0f, 20.0f), time );
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
   END_TEST;
 }
 
@@ -1041,13 +952,17 @@ int UtcDaliPanGestureSignalReceptionActorBecomesUntouchable(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pan in actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Pan continues within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
+
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Actor become invisible - actor should not receive the next pan
@@ -1059,107 +974,10 @@ int UtcDaliPanGestureSignalReceptionActorBecomesUntouchable(void)
 
   // Gesture ends within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 10.0f), Vector2(10.0f, 10.0f), 10));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  END_TEST;
-}
-
-int UtcDaliPanGestureSignalReceptionMultipleGestureDetectors(void)
-{
-  TestApplication application;
-  Dali::TestGestureManager& gestureManager = application.GetGestureManager();
-
-  Actor first = Actor::New();
-  first.SetSize(100.0f, 100.0f);
-  first.SetAnchorPoint(AnchorPoint::TOP_LEFT);
-  Stage::GetCurrent().Add(first);
-
-  Actor second = Actor::New();
-  second.SetSize(100.0f, 100.0f);
-  second.SetAnchorPoint(AnchorPoint::TOP_LEFT);
-  first.Add(second);
-
-  // Render and notify
-  application.SendNotification();
-  application.Render();
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  PanGestureDetector firstDetector = PanGestureDetector::New();
-  firstDetector.Attach(first);
-  firstDetector.DetectedSignal().Connect(&application, functor);
-
-  // secondDetector is scoped
-  {
-    // Reset gestureManager statistics
-    gestureManager.Initialize();
-
-    PanGestureDetector secondDetector = PanGestureDetector::New();
-    secondDetector.SetMinimumTouchesRequired(2);
-    secondDetector.SetMaximumTouchesRequired(2);
-    secondDetector.Attach(second);
-    secondDetector.DetectedSignal().Connect(&application, functor);
-
-    DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-    DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-    DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-    // Start pan within second actor's area
-    application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10, 2));
-    application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10, 2));
-    DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-    DALI_TEST_EQUALS(true, second == data.pannedActor, TEST_LOCATION);
 
-    // Two touch pan changes to single touch - we should receive a finished state
-    data.Reset();
-    application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10));
-    DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-    DALI_TEST_EQUALS(Gesture::Finished, data.receivedGesture.state, TEST_LOCATION);
-    DALI_TEST_EQUALS(true, second == data.pannedActor, TEST_LOCATION);
-
-    // Pan continues as single touch gesture - we should not receive any gesture
-    data.Reset();
-    application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 10.0f), Vector2(30.0f, 10.0f), 10));
-    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
 
-    // Pan ends - still no signal
-    data.Reset();
-    application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(30.0f, 10.0f), Vector2(30.0f, 20.0f), 10));
-    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-    // Single touch pan starts - first actor should be panned
-    data.Reset();
-    application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-    application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-    DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-    DALI_TEST_EQUALS(true, first == data.pannedActor, TEST_LOCATION);
-
-    // Pan changes to double-touch - we should receive a finished state
-    data.Reset();
-    application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10, 2));
-    DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-    DALI_TEST_EQUALS(Gesture::Finished, data.receivedGesture.state, TEST_LOCATION);
-    DALI_TEST_EQUALS(true, first == data.pannedActor, TEST_LOCATION);
-
-    // Pan continues as double touch gesture - we should not receive any gesture
-    data.Reset();
-    application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 10.0f), Vector2(30.0f, 10.0f), 10));
-    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-    // Pan ends - still no signal
-    data.Reset();
-    application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(30.0f, 10.0f), Vector2(30.0f, 20.0f), 10));
-    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-    // Reset gesture manager statistics
-    gestureManager.Initialize();
-  }
-
-  // secondDetector has now been deleted.  Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
 
@@ -1201,15 +1019,19 @@ int UtcDaliPanGestureSignalReceptionMultipleDetectorsOnActor(void)
   secondDetector.Attach(actor2);
 
   // Pan in actor's area - both detector's functors should be called
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
 
   // Pan continues in actor's area - both detector's functors should be called
   firstData.Reset();
   secondData.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(10.0f, 20.0f), 10));
+
+  TestMovePan( application, Vector2(10.0f, 20.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
 
@@ -1217,15 +1039,18 @@ int UtcDaliPanGestureSignalReceptionMultipleDetectorsOnActor(void)
   firstDetector.Detach(actor);
   firstData.Reset();
   secondData.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(20.0f, 20.0f), Vector2(10.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
 
   // New pan on actor, only secondDetector has actor attached
   firstData.Reset();
   secondData.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
 
@@ -1233,69 +1058,12 @@ int UtcDaliPanGestureSignalReceptionMultipleDetectorsOnActor(void)
   secondDetector.Detach(actor);
   firstData.Reset();
   secondData.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(20.0f, 20.0f), Vector2(10.0f, 20.0f), 10));
-  DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(false, secondData.functorCalled, TEST_LOCATION);
-  END_TEST;
-}
-
-int UtcDaliPanGestureSignalReceptionMultipleStarted(void)
-{
-  // Should handle two started events gracefully.
-
-  TestApplication application;
-
-  Actor actor = Actor::New();
-  actor.SetSize(100.0f, 100.0f);
-  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
-  Stage::GetCurrent().Add(actor);
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  PanGestureDetector detector = PanGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect(&application, functor);
 
-  // Render and notify
-  application.SendNotification();
-  application.Render();
-
-  // Start pan in actor's area
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-
-  // Send another start in actor's area
-  data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-
-  // Add a child actor to overlap actor and send another start in actor's area
-  Actor child = Actor::New();
-  child.SetSize(100.0f, 100.0f);
-  child.SetAnchorPoint(AnchorPoint::CENTER);
-  child.SetParentOrigin(ParentOrigin::CENTER);
-  actor.Add(child);
+  TestMovePan( application, Vector2(10.0f, 20.0f), time );
 
-  TouchEventFunctor touchFunctor;
-  child.TouchedSignal().Connect(&application, touchFunctor);
-
-  // Render and notify
-  application.SendNotification();
-  application.Render();
-
-  // Send another possible and start in actor's area
-  data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, secondData.functorCalled, TEST_LOCATION);
 
-  // Send another start in actor's area
-  data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
 
@@ -1329,8 +1097,9 @@ int UtcDaliPanGestureSignalReceptionEnsureCorrectSignalling(void)
   application.Render();
 
   // Start pan in actor1's area, only data1 should be set
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data1.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
   END_TEST;
@@ -1357,7 +1126,11 @@ int UtcDaliPanGestureSignalReceptionDifferentPossible(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Gesture possible in actor's area.
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+//  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartLongPress( application, 10.0f, 20.0f, time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Move actor somewhere else
@@ -1368,12 +1141,16 @@ int UtcDaliPanGestureSignalReceptionDifferentPossible(void)
   application.Render();
 
   // Emit Started event, we should not receive the long press.
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+  TestEndPan( application, Vector2( 26.0f, 20.0f ), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // LongPress possible in empty area.
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestStartLongPress( application, 10.0f, 20.0f, time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Move actor in to the long press position.
@@ -1384,51 +1161,19 @@ int UtcDaliPanGestureSignalReceptionDifferentPossible(void)
   application.Render();
 
   // Emit Started event, we should not receive the long press.
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+  TestEndPan( application, Vector2( 26.0f, 20.0f ), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Normal long press in actor's area for completeness.
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+  TestEndPan( application, Vector2( 26.0f, 20.0f ), time );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliPanGestureEmitIncorrectState(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  PanGestureDetector detector = PanGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Try a Clear state
-  try
-  {
-    application.ProcessEvent(GeneratePan(Gesture::Clear, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-    tet_result(TET_FAIL);
-  }
-  catch ( Dali::DaliException& e )
-  {
-    DALI_TEST_ASSERT( e, "Incorrect state", TEST_LOCATION );
-  }
-  END_TEST;
-}
-
 int UtcDaliPanGestureActorUnstaged(void)
 {
   TestApplication application;
@@ -1453,11 +1198,14 @@ int UtcDaliPanGestureActorUnstaged(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Emit signals
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(26.0f, 20.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1476,14 +1224,20 @@ int UtcDaliPanGestureActorUnstaged(void)
   stateToUnstage = Gesture::Continuing;
 
   // Emit signals
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1502,14 +1256,19 @@ int UtcDaliPanGestureActorUnstaged(void)
   stateToUnstage = Gesture::Finished;
 
   // Emit signals
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   tet_result( TET_PASS ); // If we get here then we have handled actor stage removal gracefully.
   END_TEST;
@@ -1551,8 +1310,9 @@ int UtcDaliPanGestureActorStagedAndDestroyed(void)
   // position, we should still not be signalled.
 
   // Emit signals
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1568,18 +1328,23 @@ int UtcDaliPanGestureActorStagedAndDestroyed(void)
   application.Render();
 
   // Continue signal emission
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
   // Here we delete an actor in started, we should not receive any subsequent signalling.
 
   // Emit signals
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1595,10 +1360,14 @@ int UtcDaliPanGestureActorStagedAndDestroyed(void)
   application.Render();
 
   // Continue signal emission
-  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestMovePan( application, Vector2(26.0f, 4.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+
+  TestEndPan( application, Vector2(10.0f, 4.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -1781,38 +1550,46 @@ int UtcDaliPanGestureAngleProcessing(void)
   childDetector.DetectedSignal().Connect(&application, childFunctor);
 
   // Generate an Up pan gesture, only parent should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10 ) );
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 20.0f, 4.0f ), time );
+
   DALI_TEST_EQUALS( true,  parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 4.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a Right pan gesture, only child should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(30.0f, 20.0f), 10 ) );
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 36.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( true,  childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(4.0f, 20.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a Down pan gesture, no one should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(20.0f, 30.0f), 10 ) );
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 20.0f, 36.0f ), time );
+
   DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 36.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a Left pan gesture, no one should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(10.0f, 20.0f), 10 ) );
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 4.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(4.0f, 20.0f), time );
   parentData.Reset();
   childData.Reset();
   END_TEST;
@@ -1906,74 +1683,79 @@ int UtcDaliPanGestureDirectionProcessing(void)
   childDetector.DetectedSignal().Connect(&application, childFunctor);
 
   // Generate an Up pan gesture, only parent should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(20.0f, 10.0f), 10 ) );
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 20.0f, 4.0f ), time );
+
   DALI_TEST_EQUALS( true,  parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 20.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a Right pan gesture, only child should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(30.0f, 20.0f), 10 ) );
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 36.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( true,  childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 20.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a Down pan gesture, only parent should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(20.0f, 30.0f), 10 ) );
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 20.0f, 36.0f ), time );
+
   DALI_TEST_EQUALS( true,  parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 20.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a Left pan gesture, only child should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(10.0f, 20.0f), 10 ) );
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 4.0f, 20.0f ), time );
+
   DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( true,  childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 20.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a pan at -45 degrees, no one should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(10.0f, 30.0f), 10 ) );
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 9.0f, 31.0f ), time );
+
   DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 20.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a pan at 45 degrees, no one should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(30.0f, 30.0f), 10 ) );
-  DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
-  DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
-  parentData.Reset();
-  childData.Reset();
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 31.0f, 31.0f ), time );
 
-  // Generate a pan at 135 degrees, no one should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(10.0f, 30.0f), 10 ) );
   DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 20.0f), time );
+  time += TestGetFrameInterval();
   parentData.Reset();
   childData.Reset();
 
   // Generate a pan at -135 degrees, no one should receive it.
-  application.ProcessEvent( GeneratePan( Gesture::Possible, Vector2(20.0f, 20.0f), Vector2(20.0f, 20.0f), 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  Vector2(20.0f, 20.0f), Vector2(10.0f, 10.0f), 10 ) );
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  Vector2( 4.0f, 4.0f ), time );
+
   DALI_TEST_EQUALS( false, parentData.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( false, childData.functorCalled,  TEST_LOCATION );
-  application.ProcessEvent( GeneratePan( Gesture::Finished,  Vector2(20.0f, 30.0f), Vector2(20.0f, 20.0f), 10 ) );
+
+  TestEndPan( application, Vector2(20.0f, 20.0f), time );
   parentData.Reset();
   childData.Reset();
   END_TEST;
@@ -2014,9 +1796,25 @@ int UtcDaliPanGestureNoPredictionNoSmoothing(void)
   application.SendNotification();
   application.Render();
 
-  Vector2 direction(Vector2::XAXIS * -5.0f);
   Vector2 startPosition( 1.0f, 1.0f );
-  PerformSwipeGestureSwipe(application, startPosition, direction, PAN_GESTURE_UPDATE_COUNT, 1, true, true);
+  Vector2 position( -14.0f, 1.0f );
+  Vector2 direction(Vector2::XAXIS * -5.0f);
+  uint32_t time = 100;
+
+  TestStartPan( application, startPosition, position, time );
+
+  for(int i = 0; i < 47; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  TestEndPan( application, position, time );
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.called, true, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.screenPosition, startPosition + (direction * PAN_GESTURE_UPDATE_COUNT), 0.1f, TEST_LOCATION );
@@ -2061,15 +1859,30 @@ int UtcDaliPanGestureNoPredictionSmoothing(void)
   application.SendNotification();
   application.Render();
 
+  Vector2 startPosition( 1.0f, 1.0f );
+  Vector2 position( -14.0f, 1.0f );
   Vector2 direction(Vector2::XAXIS * -5.0f);
-  Vector2 previousPosition( 20.0f, 20.0f );
-  Vector2 currentPosition( 20.0f, 10.0f );
-  PerformSwipeGestureSwipe(application, Vector2(1.0f, 1.0f), direction, PAN_GESTURE_UPDATE_COUNT, 1, true, true);
+  uint32_t time = 100;
+
+  TestStartPan( application, startPosition, position, time );
+
+  for(int i = 0; i < 47; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  TestEndPan( application, position, time );
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.called, true, TEST_LOCATION );
   // Take into account resampling done when prediction is off.
-  DALI_TEST_EQUALS( constraintData.screenPosition, Vector2(1.0f, 1.0f) + (direction * (PAN_GESTURE_UPDATE_COUNT - 0.25f)), 0.15f, TEST_LOCATION );
-  DALI_TEST_EQUALS( constraintData.localPosition,  Vector2(1.0f, 1.0f) + (direction * (PAN_GESTURE_UPDATE_COUNT - 0.25f)), 0.15f, TEST_LOCATION );
+  DALI_TEST_EQUALS( constraintData.screenPosition, startPosition + (direction * (PAN_GESTURE_UPDATE_COUNT - 0.25f)), 0.15f, TEST_LOCATION );
+  DALI_TEST_EQUALS( constraintData.localPosition,  startPosition + (direction * (PAN_GESTURE_UPDATE_COUNT - 0.25f)), 0.15f, TEST_LOCATION );
 
   constraintData.Reset();
   END_TEST;
@@ -2110,10 +1923,25 @@ int UtcDaliPanGesturePredictionNoSmoothing(void)
   application.SendNotification();
   application.Render();
 
+  Vector2 startPosition( 1.0f, 1.0f );
+  Vector2 position( -1.0f, 1.0f );
   Vector2 direction(Vector2::XAXIS * -1.0f);
-  Vector2 previousPosition( 20.0f, 20.0f );
-  Vector2 currentPosition( 20.0f, 10.0f );
-  PerformSwipeGestureSwipe(application, Vector2(1.0f, 1.0f), direction, PAN_GESTURE_UPDATE_COUNT, 1, true, true);
+  uint32_t time = 100;
+
+  TestStartPan( application, startPosition, position, time );
+
+  for(int i = 0; i < 47; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  TestEndPan( application, position, time );
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.called, true, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.screenPosition, Vector2(1.0f, 1.0f) + (direction * PAN_GESTURE_UPDATE_COUNT), 10.0f, TEST_LOCATION );
@@ -2158,10 +1986,25 @@ int UtcDaliPanGesturePredictionSmoothing01(void)
   application.SendNotification();
   application.Render();
 
+  Vector2 startPosition( 1.0f, 1.0f );
+  Vector2 position( -1.0f, 1.0f );
   Vector2 direction(Vector2::XAXIS * -1.0f);
-  Vector2 previousPosition( 20.0f, 20.0f );
-  Vector2 currentPosition( 20.0f, 10.0f );
-  PerformSwipeGestureSwipe(application, Vector2(1.0f, 1.0f), direction, PAN_GESTURE_UPDATE_COUNT, 1, true, true);
+  uint32_t time = 100;
+
+  TestStartPan( application, startPosition, position, time );
+
+  for(int i = 0; i < 47; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  TestEndPan( application, position, time );
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.called, true, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.screenPosition, Vector2(1.0f, 1.0f) + (direction * PAN_GESTURE_UPDATE_COUNT), 10.0f, TEST_LOCATION );
@@ -2209,15 +2052,59 @@ int UtcDaliPanGesturePredictionSmoothing02(void)
   application.SendNotification();
   application.Render();
 
+  Vector2 startPosition( 2.0f, 2.0f );
+  Vector2 position( 4.0f, 2.0f );
   Vector2 directionX(Vector2::XAXIS);
   Vector2 directionY(Vector2::YAXIS);
-  Vector2 position = PerformSwipeGestureSwipe(application, Vector2(2.0f, 2.0f), directionX, 10, 1, true, false);
-  position = PerformSwipeGestureSwipe(application, position, directionX * 10.0f, 1, 1, false, false);
-  position = PerformSwipeGestureSwipe(application, position, directionX * -1.0f, 2, 1, false, false);
-  position = PerformSwipeGestureSwipe(application, position, directionX, 10, 1, false, true);
-  position = PerformSwipeGestureSwipe(application, position, directionY, 10, 1, true, false);
-  position = PerformSwipeGestureSwipe(application, position, directionY * -1.0f, 2, 1, false, false);
-  position = PerformSwipeGestureSwipe(application, position, directionY, 10, 1, false, true);
+  uint32_t time = 100;
+
+  TestStartPan( application, startPosition, position, time );
+
+  for(int i = 0; i < 7; i++ )
+  {
+    position += directionX;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  position += directionX * 10.0f;
+  TestMovePan( application, position, time );
+  time += TestGetFrameInterval();
+  application.SendNotification();
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
+  for(int i = 0; i < 2; i++ )
+  {
+    position += ( directionX * -1.0f );
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  for(int i = 0; i < 10; i++ )
+  {
+    position += directionX;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  for(int i = 0; i < 10; i++ )
+  {
+    position += directionY;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  TestEndPan( application, position, time );
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.called, true, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.screenPosition, Vector2(2.0f, 2.0f) + position, 10.0f, TEST_LOCATION );
@@ -2272,8 +2159,25 @@ int UtcDaliPanGesturePrediction2SmoothingMultiTap01(void)
   application.SendNotification();
   application.Render();
 
+  Vector2 startPosition( 2.0f, 2.0f );
+  Vector2 position( -1.0f, 2.0f );
   Vector2 direction(Vector2::XAXIS * -1.0f);
-  Vector2 position = PerformSwipeGestureSwipe(application, Vector2(2.0f, 2.0f), direction, 10, 1, true, true);
+  uint32_t time = 100;
+
+  TestStartPan( application, startPosition, position, time );
+
+  for(int i = 0; i < 27; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  TestEndPan( application, position, time );
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.called, true, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.screenPosition, Vector2(2.0f, 2.0f) + position, 10.0f, TEST_LOCATION );
@@ -2329,11 +2233,57 @@ int UtcDaliPanGesturePrediction2SmoothingMultiTap02(void)
   application.SendNotification();
   application.Render();
 
+  Vector2 startPosition( 2.0f, 2.0f );
+  Vector2 position( 17.0f, 2.0f );
   Vector2 direction(Vector2::XAXIS * -1.0f);
-  Vector2 position = PerformSwipeGestureSwipe(application, Vector2(2.0f, 2.0f), direction, 10, 3, true, false);
-  position = PerformSwipeGestureSwipe(application, position, direction, 10, 0, false, false);
-  position = PerformSwipeGestureSwipe(application, position, direction, 10, 1, false, false, 0);
-  position = PerformSwipeGestureSwipe(application, position, direction, 10, 1, false, true);
+  uint32_t time = 100;
+
+  TestStartPan( application, startPosition, position, time );
+
+  for(int i = 0; i < 10; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  for(int i = 0; i < 10; i++ )
+  {
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  for(int i = 0; i < 10; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  for(int i = 0; i < 10; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  TestEndPan( application, position, time );
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.called, true, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.screenPosition, Vector2(2.0f, 2.0f) + position, 10.0f, TEST_LOCATION );
@@ -2388,11 +2338,56 @@ int UtcDaliPanGesturePrediction2Smoothing(void)
   application.SendNotification();
   application.Render();
 
+  Vector2 startPosition( 2.0f, 2.0f );
+  Vector2 position( 17.0f, 2.0f );
   Vector2 direction(Vector2::XAXIS * -1.0f);
-  Vector2 position = PerformSwipeGestureSwipe(application, Vector2(2.0f, 2.0f), direction, 10, 1, true, false);
-  position = PerformSwipeGestureSwipe(application, position, direction, 1, 3, false, false);
-  position = PerformSwipeGestureSwipe(application, position, direction, 5, 0, false, false);
-  position = PerformSwipeGestureSwipe(application, position, direction, 10, 1, false, true);
+  uint32_t time = 100;
+
+  TestStartPan( application, startPosition, position, time );
+
+  for(int i = 0; i < 10; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+
+  position += direction;
+  TestMovePan( application, position, time );
+  time += TestGetFrameInterval();
+
+  position += direction;
+  TestMovePan( application, position, time );
+  time += TestGetFrameInterval();
+
+  position += direction;
+  TestMovePan( application, position, time );
+  time += TestGetFrameInterval();
+
+  application.SendNotification();
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
+  for(int i = 0; i < 5; i++ )
+  {
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  for(int i = 0; i < 10; i++ )
+  {
+    position += direction;
+    TestMovePan( application, position, time );
+    time += TestGetFrameInterval();
+    application.SendNotification();
+    application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+  }
+
+  TestEndPan( application, position, time );
+  application.Render(TestApplication::DEFAULT_RENDER_INTERVAL);
+
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.called, true, TEST_LOCATION );
   DALI_TEST_EQUALS( constraintData.screenPosition, Vector2(2.0f, 2.0f) + position, 10.0f, TEST_LOCATION );
@@ -2502,10 +2497,9 @@ int UtcDaliPanGestureSetPropertiesAlreadyPanning(void)
   application.SendNotification();
   application.Render();
 
-  Vector2 previousPosition( 20.0f, 20.0f );
-  Vector2 currentPosition( 20.0f, 10.0f );
-  application.ProcessEvent( GeneratePan( Gesture::Possible, previousPosition, previousPosition, 10 ) );
-  application.ProcessEvent( GeneratePan( Gesture::Started,  previousPosition, currentPosition, 10 ) );
+  Vector2 currentPosition( 20.0f, 4.0f );
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 20.0f, 20.0f ),  currentPosition, time );
   DALI_TEST_EQUALS( true,  data.functorCalled, TEST_LOCATION );
 
   Vector2 screenPosition( 100.0f, 20.0f );
@@ -2665,9 +2659,11 @@ int UtcDaliPanGestureLayerConsumesTouch(void)
   application.Render();
 
   // Emit signals, should receive
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  uint32_t time = 100;
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+  TestEndPan( application, Vector2(26.0f, 20.0f), time );
+  time += TestGetFrameInterval();
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -2679,9 +2675,9 @@ int UtcDaliPanGestureLayerConsumesTouch(void)
   application.Render();
 
   // Emit the same signals again, should not receive
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestStartPan( application, Vector2( 10.0f, 20.0f ),  Vector2( 26.0f, 20.0f ), time );
+  TestEndPan( application, Vector2(26.0f, 20.0f), time );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -2708,10 +2704,13 @@ int UtcDaliPanGestureNoTimeDiff(void)
   application.SendNotification();
   application.Render();
 
-  // Emit signals, should receive
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 0));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 0));
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 0));
+  // As normal helper function adds intervals between presses we must generate the sequence
+  // using other helper functions
+  TestStartLongPress( application, 10.0f, 20.0f, 100 );   // Used to send a down press event
+  TestMovePan( application, Vector2(26.0f, 20.0f), 100 );
+  TestMovePan( application, Vector2(26.0f, 20.0f), 100 ); // 2 motions required to trigger
+  TestEndPan( application, Vector2(26.0f, 20.0f), 100 );
+
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_CHECK( !std::isinf( data.receivedGesture.velocity.x ) );
   DALI_TEST_CHECK( !std::isinf( data.receivedGesture.velocity.y ) );
diff --git a/automated-tests/src/dali/utc-Dali-PanGestureRecognizer.cpp b/automated-tests/src/dali/utc-Dali-PanGestureRecognizer.cpp
new file mode 100644 (file)
index 0000000..64b4052
--- /dev/null
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+#include <dali/integration-api/input-options.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/pan-gesture-event.h>
+#include <dali-test-suite-utils.h>
+#include <test-touch-utils.h>
+
+using namespace Dali;
+
+///////////////////////////////////////////////////////////////////////////////
+namespace
+{
+
+struct SignalData
+{
+  SignalData()
+  : functorCalled(false),
+    voidFunctorCalled(false),
+    receivedGesture()
+  {}
+
+  void Reset()
+  {
+    functorCalled = false;
+    voidFunctorCalled = false;
+
+    receivedGesture.state = Gesture::Started;
+
+    pannedActor.Reset();
+  }
+
+  bool functorCalled;
+  bool voidFunctorCalled;
+  PanGesture receivedGesture;
+  Actor pannedActor;
+};
+
+// Functor that sets the data when called
+struct GestureReceivedFunctor
+{
+  GestureReceivedFunctor(SignalData& data) : signalData(data) { }
+
+  void operator()(Actor actor, const PanGesture& pan)
+  {
+    signalData.functorCalled = true;
+    signalData.receivedGesture = pan;
+    signalData.pannedActor = actor;
+  }
+
+  void operator()()
+  {
+    signalData.voidFunctorCalled = true;
+  }
+
+  SignalData& signalData;
+};
+
+
+Integration::TouchEvent GenerateSingleTouch( PointState::Type state, const Vector2& screenPosition, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( state );
+  point.SetScreenPosition( screenPosition );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+Integration::TouchEvent GenerateDoubleTouch( PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( stateA );
+  point.SetScreenPosition( screenPositionA );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  point.SetScreenPosition( screenPositionB );
+  point.SetState( stateB);
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+
+} // anon namespace
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+int UtcDaliPanGestureRecognizerBasicNoAction(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerBasic(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 60.0f ), 152 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerBasicInterrupted(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 25.0f ), 151 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::INTERRUPTED, Vector2( 20.0f, 30.0f ), 152 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerBasicShortest(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 40.0f ), 155 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerBasicFailToStart(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 50.0f ), PointState::DOWN, Vector2( 40.0f, 40.0f ), 153 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerBasicStationary(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 50.0f ), 152 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::STATIONARY, Vector2( 20.0f, 50.0f ), 153 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), 154 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerNewParametersFail(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  detector.SetMaximumTouchesRequired(2);
+  detector.SetMinimumTouchesRequired(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 60.0f ), 152 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerNewParametersSuccess(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  detector.SetMaximumTouchesRequired(2);
+  detector.SetMinimumTouchesRequired(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 50.0f ), PointState::DOWN, Vector2( 20.0f, 40.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 40.0f, 50.0f ), PointState::MOTION, Vector2( 40.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 50.0f, 50.0f ), PointState::MOTION, Vector2( 50.0f, 40.0f ), 152 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerNewParametersEndFewerTouches01(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  detector.SetMaximumTouchesRequired(2);
+  detector.SetMinimumTouchesRequired(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 50.0f ), PointState::DOWN, Vector2( 20.0f, 40.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 40.0f, 50.0f ), PointState::MOTION, Vector2( 40.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 50.0f, 50.0f ), PointState::MOTION, Vector2( 50.0f, 40.0f ), 152 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::STATIONARY, Vector2( 50.0f, 50.0f ), 153 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerNewParametersEndFewerTouches02(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  detector.SetMaximumTouchesRequired(2);
+  detector.SetMinimumTouchesRequired(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 50.0f ), PointState::DOWN, Vector2( 20.0f, 40.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 40.0f, 50.0f ), PointState::MOTION, Vector2( 40.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 50.0f, 50.0f ), PointState::MOTION, Vector2( 50.0f, 40.0f ), 152 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::STATIONARY, Vector2( 50.0f, 50.0f ), PointState::UP, Vector2( 50.0f, 40.0f ), 153 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerNewParametersNoStart(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  detector.SetMaximumTouchesRequired(2);
+  detector.SetMinimumTouchesRequired(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 50.0f ), PointState::DOWN, Vector2( 20.0f, 40.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 40.0f, 50.0f ), PointState::MOTION, Vector2( 40.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 50.0f, 50.0f ), 153 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerNewParametersSlowRelease(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  detector.SetMaximumTouchesRequired(2);
+  detector.SetMinimumTouchesRequired(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 50.0f ), PointState::DOWN, Vector2( 20.0f, 40.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 40.0f, 50.0f ), PointState::MOTION, Vector2( 40.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 50.0f, 50.0f ), PointState::MOTION, Vector2( 50.0f, 40.0f ), 152 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 60.0f, 50.0f ), PointState::MOTION, Vector2( 60.0f, 40.0f ), 153 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 70.0f, 50.0f ), PointState::MOTION, Vector2( 70.0f, 40.0f ), 154 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 70.0f, 50.0f ), 155 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerOtherEvent(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 151 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 60.0f ), 152 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 60.0f ), 153 ) );      // Exercise default case in Started case. Not sure if realistic
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 65.0f ), 154 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerSlowMoving(void)
+{
+  TestApplication application;
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 251 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 60.0f ), 352 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 70.0f ), 453 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 80.0f ), 554 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 90.0f ), 655 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerNewParamsMinNum(void)
+{
+  TestApplication application;
+
+  Integration::SetPanGestureMinimumPanEvents(8);
+
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 251 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 60.0f ), 352 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 70.0f ), 453 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 80.0f ), 554 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 90.0f ), 655 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPanGestureRecognizerNewParamsMinDistance(void)
+{
+  TestApplication application;
+
+  Integration::SetPanGestureMinimumDistance(100);
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), 251 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 60.0f ), 352 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 70.0f ), 453 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 80.0f ), 554 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 90.0f ), 655 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
index f877a00..448cecd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
 #include <stdlib.h>
 #include <dali/public-api/dali-core.h>
 #include <dali/integration-api/events/touch-event-integ.h>
-#include <dali/integration-api/events/pinch-gesture-event.h>
 #include <dali/integration-api/render-task-list-integ.h>
 #include <dali-test-suite-utils.h>
 #include <test-touch-utils.h>
@@ -121,22 +120,6 @@ struct TouchEventFunctor
   }
 };
 
-// Generate a PinchGestureEvent to send to Core
-Integration::PinchGestureEvent GeneratePinch(
-    Gesture::State state,
-    float scale,
-    float speed,
-    Vector2 centerpoint)
-{
-  Integration::PinchGestureEvent pinch(state);
-
-  pinch.scale = scale;
-  pinch.speed = speed;
-  pinch.centerPoint = centerpoint;
-
-  return pinch;
-}
-
 } // anon namespace
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -262,17 +245,23 @@ int UtcDaliPinchGestureSignalReceptionNegative(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do a pinch outside actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 45.0f, Vector2(112.0f, 112.0f)));
+  TestStartPinch( application,  Vector2( 112.0f, 62.0f ), Vector2( 112.0f, 162.0f ),
+                                Vector2( 112.0f, 100.0f ), Vector2( 112.0f, 124.0f ), 100 );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Continue pinch into actor's area - we should still not receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 4.5f, 95.0f, Vector2(20.0f, 20.0f)));
+  TestContinuePinch( application, Vector2( 112.0f, 100.0f ), Vector2( 112.0f, 124.0f ),
+                                  Vector2( 5.0f, 5.0f ), Vector2( 35.0f, 35.0f ), 200 );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Stop pinching - we should still not receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(12.0f, 12.0f)));
+  TestEndPinch( application,  Vector2( 6.0f, 6.0f ), Vector2( 18.0f, 18.0f ),
+                              Vector2( 10.0f, 8.0f ), Vector2( 14.0f, 16.0f ), 300 );
+
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -298,38 +287,42 @@ int UtcDaliPinchGestureSignalReceptionDownMotionLeave(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pan within the actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 20.0f)));
+  TestStartPinch( application,  Vector2( 5.0f, 20.0f ), Vector2( 35.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(50.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.666f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(66.666f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
 
   // Continue the pan within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 5.0f, 90.0f, Vector2(21.0f, 20.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 17.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 400 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
-  DALI_TEST_EQUALS(5.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(90.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.2666f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(80.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(21.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
 
   // Pan Gesture leaves actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 10.0f, 15.5f, Vector2(320.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 17.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                                  Vector2( 300.0f, 10.0f ), Vector2( 340.0f, 10.0f ), 1000 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(15.5f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(1.333f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(213.333f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(320.0f, 10.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
 
   // Gesture ends - we would receive a finished state
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 15.2f, 12.1f, Vector2(310.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 300.0f, 10.0f ), Vector2( 340.0f, 10.0f ),
+                              Vector2( 305.0f, 10.0f ), Vector2( 315.0f, 10.0f ), 1500);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Finished, data.receivedGesture.state, TEST_LOCATION);
-  DALI_TEST_EQUALS(15.2f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(12.1f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.333f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(600.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(310.0f, 10.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
   END_TEST;
 }
@@ -355,73 +348,36 @@ int UtcDaliPinchGestureSignalReceptionDownMotionUp(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pinch within the actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 20.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(50.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.555f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(106.667f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
 
   // Continue the pinch within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
-  DALI_TEST_EQUALS(5.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(25.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.277f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(66.666f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
 
   // Gesture ends within actor's area - we would receive a finished state
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Finished, data.receivedGesture.state, TEST_LOCATION);
-  DALI_TEST_EQUALS(5.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(25.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.055f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(160.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliPinchGestureSignalReceptionCancelled(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();
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  PinchGestureDetector detector = PinchGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect(&application, functor);
-
-  // Start pinch within the actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 20.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
-
-
-  // Continue the pinch within the actor's area - we should still receive the signal
-  data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
-
-  // The gesture is cancelled
-  data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Cancelled, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(Gesture::Cancelled, data.receivedGesture.state, TEST_LOCATION);
-  END_TEST;
-}
-
 int UtcDaliPinchGestureSignalReceptionDetach(void)
 {
   TestApplication application;
@@ -443,20 +399,23 @@ int UtcDaliPinchGestureSignalReceptionDetach(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pinch within the actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 20.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
 
 
   // Continue the pinch within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
 
   // Gesture ends within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Finished, data.receivedGesture.state, TEST_LOCATION);
 
@@ -465,9 +424,7 @@ int UtcDaliPinchGestureSignalReceptionDetach(void)
 
   // Ensure we are no longer signalled
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 20.0f)));
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+  TestGeneratePinch(  application );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -493,13 +450,15 @@ int UtcDaliPinchGestureSignalReceptionDetachWhilePinching(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pinch within the actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
 
   // Continue the pinch within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
 
@@ -508,7 +467,8 @@ int UtcDaliPinchGestureSignalReceptionDetachWhilePinching(void)
 
   // Gesture ends within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -545,13 +505,15 @@ int UtcDaliPinchGestureSignalReceptionActorDestroyedWhilePinching(void)
     detector.Attach(actor);
 
     // Start pinch within the actor's area
-    application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+    TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                  Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
     DALI_TEST_EQUALS(Gesture::Started, data.receivedGesture.state, TEST_LOCATION);
 
     // Continue the pinch within the actor's area - we should still receive the signal
     data.Reset();
-    application.ProcessEvent(GeneratePinch(Gesture::Continuing, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+    TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                    Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
     DALI_TEST_EQUALS(Gesture::Continuing, data.receivedGesture.state, TEST_LOCATION);
 
@@ -567,7 +529,8 @@ int UtcDaliPinchGestureSignalReceptionActorDestroyedWhilePinching(void)
 
   // Gesture ends within the area where the actor used to be
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 5.0f, 25.0f, Vector2(20.0f, 20.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -593,13 +556,15 @@ int UtcDaliPinchGestureSignalReceptionRotatedActor(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do an entire pinch, only check finished value
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(50.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(10.0f, 10.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.055f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(160.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
 
   // Rotate actor again and render and notify
   actor.SetOrientation(Dali::Degree(180.0f), Vector3::ZAXIS);
@@ -607,13 +572,15 @@ int UtcDaliPinchGestureSignalReceptionRotatedActor(void)
   application.Render();
 
   // Do an entire pinch, only check finished value
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 2100 );
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 3000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(50.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(10.0f, 10.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.055f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(160.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
 
   // Rotate actor again and render and notify
   actor.SetOrientation(Dali::Degree(270.0f), Vector3::ZAXIS);
@@ -621,13 +588,15 @@ int UtcDaliPinchGestureSignalReceptionRotatedActor(void)
   application.Render();
 
   // Do an entire pinch, only check finished value
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 4100 );
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 5000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  DALI_TEST_EQUALS(10.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(50.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(10.0f, 10.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.055f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(160.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
   END_TEST;
 }
 
@@ -665,14 +634,16 @@ int UtcDaliPinchGestureSignalReceptionChildHit(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do an entire pan, only check finished value - hits child area but parent should still receive it
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 5.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, parent == data.pinchedActor, TEST_LOCATION);
-  DALI_TEST_EQUALS(5.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(50.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(10.0f, 10.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.055f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(160.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
 
   // Attach child and generate same touch points to yield same results
   // (Also proves that you can detach and then re-attach another actor)
@@ -680,14 +651,16 @@ int UtcDaliPinchGestureSignalReceptionChildHit(void)
   detector.Detach(parent);
 
   // Do an entire pan, only check finished value
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 2100 );
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 5.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 3000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, child == data.pinchedActor, TEST_LOCATION);
-  DALI_TEST_EQUALS(5.0f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(50.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
-  DALI_TEST_EQUALS(Vector2(10.0f, 10.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(0.055f, data.receivedGesture.scale, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(160.0f, data.receivedGesture.speed, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.screenCenterPoint, 0.01f, TEST_LOCATION);
   END_TEST;
 }
 
@@ -719,13 +692,15 @@ int UtcDaliPinchGestureSignalReceptionAttachDetachMany(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pinch within second actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(120.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 102.0f, 20.0f ), Vector2( 138.0f, 20.0f ),
+                                    Vector2( 110.0f, 20.0f ), Vector2( 130.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, second == data.pinchedActor, TEST_LOCATION);
 
   // Pinch moves into first actor's area - second actor should receive the pinch
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 10.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 110.0f, 20.0f ), Vector2( 130.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, second == data.pinchedActor, TEST_LOCATION);
 
@@ -734,7 +709,8 @@ int UtcDaliPinchGestureSignalReceptionAttachDetachMany(void)
 
   // Gesture ends within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(120.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 119.0f, 20.0f ), Vector2( 121.0f, 20.0f ), 3000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -760,12 +736,14 @@ int UtcDaliPinchGestureSignalReceptionActorBecomesUntouchable(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start pinch in actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Pan continues within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 5.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Actor become invisible - actor should not receive the next pinch
@@ -777,7 +755,8 @@ int UtcDaliPinchGestureSignalReceptionActorBecomesUntouchable(void)
 
   // Gesture ends within actor's area
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 5.0f, 50.0f, Vector2(10.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 3000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -820,14 +799,16 @@ int UtcDaliPinchGestureSignalReceptionMultipleDetectorsOnActor(void)
   secondDetector.Attach(actor2);
 
   // Pinch in actor's area - both detector's functors should be called
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
 
   // Pinch continues in actor's area - both detector's functors should be called
   firstData.Reset();
   secondData.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
 
@@ -835,14 +816,16 @@ int UtcDaliPinchGestureSignalReceptionMultipleDetectorsOnActor(void)
   firstDetector.Detach(actor);
   firstData.Reset();
   secondData.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
 
   // New pinch on actor, only secondDetector has actor attached
   firstData.Reset();
   secondData.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 1500 );
   DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
 
@@ -850,69 +833,13 @@ int UtcDaliPinchGestureSignalReceptionMultipleDetectorsOnActor(void)
   secondDetector.Detach(actor);
   firstData.Reset();
   secondData.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 2000 );
   DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(false, secondData.functorCalled, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliPinchGestureSignalReceptionMultipleStarted(void)
-{
-  // Should handle two started events gracefully.
-
-  TestApplication application;
-
-  Actor actor = Actor::New();
-  actor.SetSize(100.0f, 100.0f);
-  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
-  Stage::GetCurrent().Add(actor);
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  PinchGestureDetector detector = PinchGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect(&application, functor);
-
-  // Render and notify
-  application.SendNotification();
-  application.Render();
-
-  // Start pan in actor's area
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-
-  // Send another start in actor's area
-  data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-
-  // Add a child actor to overlap actor and send another start in actor's area
-  Actor child = Actor::New();
-  child.SetSize(100.0f, 100.0f);
-  child.SetAnchorPoint(AnchorPoint::CENTER);
-  child.SetParentOrigin(ParentOrigin::CENTER);
-  actor.Add(child);
-
-  TouchEventFunctor touchFunctor;
-  child.TouchedSignal().Connect(&application, touchFunctor);
-
-  // Render and notify
-  application.SendNotification();
-  application.Render();
-
-  // Send another start in actor's area
-  data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-
-  // Send another start in actor's area
-  data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  END_TEST;
-}
-
 int UtcDaliPinchGestureSignalReceptionEnsureCorrectSignalling(void)
 {
   TestApplication application;
@@ -943,78 +870,13 @@ int UtcDaliPinchGestureSignalReceptionEnsureCorrectSignalling(void)
   application.Render();
 
   // Start pan in actor1's area, only data1 should be set
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data1.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliPinchGestureEmitIncorrectStateClear(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  PinchGestureDetector detector = PinchGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Try a Clear state
-  try
-  {
-    application.ProcessEvent(GeneratePinch(Gesture::Clear, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
-    tet_result(TET_FAIL);
-  }
-  catch ( Dali::DaliException& e )
-  {
-    DALI_TEST_ASSERT( e, "Incorrect state", TEST_LOCATION );
-  }
-  END_TEST;
-}
-
-int UtcDaliPinchGestureEmitIncorrectStatePossible(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  PinchGestureDetector detector = PinchGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Try a Possible state
-  try
-  {
-    application.ProcessEvent(GeneratePinch(Gesture::Possible, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
-    tet_result(TET_FAIL);
-  }
-  catch ( Dali::DaliException& e )
-  {
-    DALI_TEST_ASSERT( e, "Incorrect state", TEST_LOCATION );
-  }
-  END_TEST;
-}
-
 int UtcDaliPinchGestureActorUnstaged(void)
 {
   TestApplication application;
@@ -1039,10 +901,12 @@ int UtcDaliPinchGestureActorUnstaged(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Emit signals
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1061,13 +925,16 @@ int UtcDaliPinchGestureActorUnstaged(void)
   stateToUnstage = Gesture::Continuing;
 
   // Emit signals
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1086,13 +953,16 @@ int UtcDaliPinchGestureActorUnstaged(void)
   stateToUnstage = Gesture::Finished;
 
   // Emit signals
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   tet_result( TET_PASS ); // If we get here then we have handled actor stage removal gracefully.
   END_TEST;
@@ -1134,7 +1004,8 @@ int UtcDaliPinchGestureActorStagedAndDestroyed(void)
   // position, we should still not be signalled.
 
   // Emit signals
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1150,17 +1021,20 @@ int UtcDaliPinchGestureActorStagedAndDestroyed(void)
   application.Render();
 
   // Continue signal emission
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 500 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
   // Here we delete an actor in started, we should not receive any subsequent signalling.
 
   // Emit signals
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 1500 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1176,10 +1050,12 @@ int UtcDaliPinchGestureActorStagedAndDestroyed(void)
   application.Render();
 
   // Continue signal emission
-  application.ProcessEvent(GeneratePinch(Gesture::Continuing, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestContinuePinch( application, Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                  Vector2( 15.0f, 20.0f ), Vector2( 25.0f, 20.0f ), 2000 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
-  application.ProcessEvent(GeneratePinch(Gesture::Finished, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestEndPinch( application,  Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                                Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 3000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -1211,13 +1087,11 @@ int UtcDaliPinchGestureLayerConsumesTouch(void)
   application.SendNotification();
   application.Render();
 
-  Vector2 screenCoords( 50.0f, 50.0f );
-  float scale ( 10.0f );
-  float speed ( 50.0f );
-
   // Emit signals, should receive
-  application.ProcessEvent( GeneratePinch( Gesture::Started, scale, speed, screenCoords ) );
-  application.ProcessEvent( GeneratePinch( Gesture::Finished, scale, speed, screenCoords ) );
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 100 );
+  TestEndPinch( application,  Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 1000);
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1229,8 +1103,10 @@ int UtcDaliPinchGestureLayerConsumesTouch(void)
   application.Render();
 
   // Emit the same signals again, should not receive
-  application.ProcessEvent( GeneratePinch( Gesture::Started, scale, speed, screenCoords ) );
-  application.ProcessEvent( GeneratePinch( Gesture::Finished, scale, speed, screenCoords ) );
+  TestStartPinch( application,  Vector2( 2.0f, 20.0f ), Vector2( 38.0f, 20.0f ),
+                                Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ), 1500 );
+  TestEndPinch( application,  Vector2( 10.0f, 20.0f ), Vector2( 30.0f, 20.0f ),
+                              Vector2( 19.0f, 20.0f ), Vector2( 21.0f, 20.0f ), 2000);
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
diff --git a/automated-tests/src/dali/utc-Dali-PinchGestureRecognizer.cpp b/automated-tests/src/dali/utc-Dali-PinchGestureRecognizer.cpp
new file mode 100644 (file)
index 0000000..93c6f29
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+#include <dali/integration-api/input-options.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/pinch-gesture-event.h>
+#include <dali-test-suite-utils.h>
+#include <test-touch-utils.h>
+
+using namespace Dali;
+
+///////////////////////////////////////////////////////////////////////////////
+namespace
+{
+
+struct SignalData
+{
+  SignalData()
+  : functorCalled(false),
+    voidFunctorCalled(false),
+    receivedGesture(Gesture::Started)
+  {}
+
+  void Reset()
+  {
+    functorCalled = false;
+    voidFunctorCalled = false;
+
+    receivedGesture.state = Gesture::Started;
+
+    pinchedActor.Reset();
+  }
+
+  bool functorCalled;
+  bool voidFunctorCalled;
+  PinchGesture receivedGesture;
+  Actor pinchedActor;
+};
+
+// Functor that sets the data when called
+struct GestureReceivedFunctor
+{
+  GestureReceivedFunctor(SignalData& data) : signalData(data) { }
+
+  void operator()(Actor actor, const PinchGesture& pinch)
+  {
+    signalData.functorCalled = true;
+    signalData.receivedGesture = pinch;
+    signalData.pinchedActor = actor;
+  }
+
+  void operator()()
+  {
+    signalData.voidFunctorCalled = true;
+  }
+
+  SignalData& signalData;
+};
+
+
+Integration::TouchEvent GenerateSingleTouch( PointState::Type state, const Vector2& screenPosition, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( state );
+  point.SetScreenPosition( screenPosition );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+Integration::TouchEvent GenerateDoubleTouch( PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( stateA );
+  point.SetScreenPosition( screenPositionA );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  point.SetScreenPosition( screenPositionB );
+  point.SetState( stateB);
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+
+} // anon namespace
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+int UtcDaliPinchGestureRecognizerBasicNoAction(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerBasic(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 28.0f ), PointState::MOTION, Vector2( 20.0f, 82.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 37.0f ), PointState::MOTION, Vector2( 20.0f, 74.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 46.0f ), PointState::MOTION, Vector2( 20.0f, 66.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 58.0f ), 190 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerEndEarly01(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 28.0f ), PointState::MOTION, Vector2( 20.0f, 82.0f ), 160 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 29.0f ), 165 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 37.0f ), PointState::MOTION, Vector2( 20.0f, 74.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 46.0f ), PointState::MOTION, Vector2( 20.0f, 66.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 58.0f ), 190 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerEndEarly02(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 28.0f ), PointState::MOTION, Vector2( 20.0f, 82.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 37.0f ), PointState::MOTION, Vector2( 20.0f, 74.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 37.0f ), PointState::UP, Vector2( 20.0f, 74.0f ), 173 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 37.0f ), PointState::DOWN, Vector2( 20.0f, 74.0f ), 178 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 46.0f ), PointState::MOTION, Vector2( 20.0f, 66.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 58.0f ), 190 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerRealistic01(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 100 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 105 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 110 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 25.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 115 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 30.0f ), PointState::MOTION, Vector2( 20.0f, 85.0f ), 120 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 35.0f ), PointState::MOTION, Vector2( 20.0f, 80.0f ), 125 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), PointState::MOTION, Vector2( 20.0f, 75.0f ), 130 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 45.0f ), PointState::MOTION, Vector2( 20.0f, 70.0f ), 135 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 50.0f ), PointState::MOTION, Vector2( 20.0f, 65.0f ), 140 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 60.0f ), 145 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 56.0f ), PointState::UP, Vector2( 20.0f, 60.0f ), 150 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 56.0f ), 155 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerRealistic02(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 100 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 105 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 110 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 25.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 115 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 30.0f ), PointState::MOTION, Vector2( 20.0f, 85.0f ), 120 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 35.0f ), PointState::MOTION, Vector2( 20.0f, 80.0f ), 125 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), PointState::MOTION, Vector2( 20.0f, 75.0f ), 130 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 45.0f ), PointState::MOTION, Vector2( 20.0f, 70.0f ), 135 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 50.0f ), PointState::MOTION, Vector2( 20.0f, 65.0f ), 140 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 60.0f ), 145 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 56.0f ), 155 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerRealistic03(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 100 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 105 ) );
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 110 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 25.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 115 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 30.0f ), PointState::MOTION, Vector2( 20.0f, 85.0f ), 120 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 35.0f ), PointState::MOTION, Vector2( 20.0f, 80.0f ), 125 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 37.0f ), PointState::MOTION, Vector2( 20.0f, 77.0f ), 127 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), PointState::MOTION, Vector2( 20.0f, 75.0f ), 130 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 47.0f ), PointState::MOTION, Vector2( 20.0f, 73.0f ), 133 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 45.0f ), PointState::MOTION, Vector2( 20.0f, 70.0f ), 135 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 47.0f ), PointState::MOTION, Vector2( 20.0f, 67.0f ), 137 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 50.0f ), PointState::MOTION, Vector2( 20.0f, 65.0f ), 140 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 53.0f ), PointState::MOTION, Vector2( 20.0f, 63.0f ), 143 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 60.0f ), 145 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 56.0f ), 155 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerMultipleDetectors(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(actor);
+
+  Actor actor2 = Actor::New();
+  actor2.SetSize(100.0f, 100.0f);
+  actor2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  actor2.SetX(100.0f);
+  Stage::GetCurrent().Add(actor2);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+  detector.Attach(actor);
+
+  PinchGestureDetector detector2 = PinchGestureDetector::New();
+  detector2.Attach(actor2);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  SignalData data2;
+  GestureReceivedFunctor functor2(data2);
+  detector2.DetectedSignal().Connect(&application, functor2);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 120.0f, 20.0f ), PointState::DOWN, Vector2( 120.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 120.0f, 28.0f ), PointState::MOTION, Vector2( 120.0f, 82.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 120.0f, 37.0f ), PointState::MOTION, Vector2( 120.0f, 74.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 120.0f, 46.0f ), PointState::MOTION, Vector2( 120.0f, 66.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 120.0f, 55.0f ), PointState::MOTION, Vector2( 120.0f, 58.0f ), 190 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::UP, Vector2( 120.0f, 55.0f ), PointState::UP, Vector2( 120.0f, 58.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, data2.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, actor2 == data2.pinchedActor, TEST_LOCATION);
+  data2.Reset();
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 250 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 28.0f ), PointState::MOTION, Vector2( 20.0f, 82.0f ), 260 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 37.0f ), PointState::MOTION, Vector2( 20.0f, 74.0f ), 270 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 46.0f ), PointState::MOTION, Vector2( 20.0f, 66.0f ), 280 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 58.0f ), 290 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, actor == data.pinchedActor, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliPinchGestureRecognizerShortDistance01(void)
+{
+  TestApplication application;
+
+  Integration::SetPinchGestureMinimumDistance(7.0f);
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 28.0f ), PointState::MOTION, Vector2( 20.0f, 82.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 30.0f ), PointState::MOTION, Vector2( 20.0f, 80.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 32.0f ), PointState::MOTION, Vector2( 20.0f, 78.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 34.0f ), PointState::MOTION, Vector2( 20.0f, 76.0f ), 190 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerShortDistance02(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  Integration::SetPinchGestureMinimumDistance(7.0f);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 28.0f ), PointState::MOTION, Vector2( 20.0f, 82.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 30.0f ), PointState::MOTION, Vector2( 20.0f, 80.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 32.0f ), PointState::MOTION, Vector2( 20.0f, 78.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 34.0f ), PointState::MOTION, Vector2( 20.0f, 76.0f ), 190 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerLongDistance01(void)
+{
+  TestApplication application;
+
+  Integration::SetPinchGestureMinimumDistance(14.0f);
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 22.0f ), PointState::MOTION, Vector2( 20.0f, 88.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 24.0f ), PointState::MOTION, Vector2( 20.0f, 86.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 26.0f ), PointState::MOTION, Vector2( 20.0f, 84.0f ), 180 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerLongDistance02(void)
+{
+  TestApplication application;
+
+  Integration::SetPinchGestureMinimumDistance(14.0f);
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 38.0f ), PointState::MOTION, Vector2( 20.0f, 72.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), PointState::MOTION, Vector2( 20.0f, 70.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 42.0f ), PointState::MOTION, Vector2( 20.0f, 68.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 44.0f ), PointState::MOTION, Vector2( 20.0f, 66.0f ), 190 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerLongDistance03(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  Integration::SetPinchGestureMinimumDistance(14.0f);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 22.0f ), PointState::MOTION, Vector2( 20.0f, 88.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 24.0f ), PointState::MOTION, Vector2( 20.0f, 86.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 26.0f ), PointState::MOTION, Vector2( 20.0f, 84.0f ), 180 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliPinchGestureRecognizerLongDistance04(void)
+{
+  TestApplication application;
+
+  PinchGestureDetector detector = PinchGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  Integration::SetPinchGestureMinimumDistance(14.0f);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 38.0f ), PointState::MOTION, Vector2( 20.0f, 72.0f ), 160 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), PointState::MOTION, Vector2( 20.0f, 70.0f ), 170 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 42.0f ), PointState::MOTION, Vector2( 20.0f, 68.0f ), 180 ) );
+  application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 44.0f ), PointState::MOTION, Vector2( 20.0f, 66.0f ), 190 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
index 03b6ecc..cef34fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
 #include <stdlib.h>
 #include <dali/public-api/dali-core.h>
 #include <dali/integration-api/events/touch-event-integ.h>
-#include <dali/integration-api/events/tap-gesture-event.h>
 #include <dali/integration-api/render-task-list-integ.h>
 #include <dali-test-suite-utils.h>
 #include <test-touch-utils.h>
@@ -116,22 +115,6 @@ struct TouchEventFunctor
   }
 };
 
-// Generate a TapGestureEvent to send to Core
-Integration::TapGestureEvent GenerateTap(
-    Gesture::State state,
-    unsigned int numberOfTaps,
-    unsigned int numberOfTouches,
-    Vector2 point)
-{
-  Integration::TapGestureEvent tap( state );
-
-  tap.numberOfTaps = numberOfTaps;
-  tap.numberOfTouches = numberOfTouches;
-  tap.point = point;
-
-  return tap;
-}
-
 } // anon namespace
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -252,121 +235,6 @@ int UtcDaliTapGestureDetectorDownCast(void)
   END_TEST;
 }
 
-int UtcDaliTapGestureSetTapsRequired(void)
-{
-  TestApplication application;
-
-  TapGestureDetector detector = TapGestureDetector::New();
-
-  const unsigned int minTaps = 3;
-  const unsigned int maxTaps = 7;
-
-  DALI_TEST_CHECK( minTaps != detector.GetMinimumTapsRequired() );
-  DALI_TEST_CHECK( maxTaps != detector.GetMaximumTapsRequired() );
-
-  detector.SetMinimumTapsRequired( minTaps );
-  detector.SetMaximumTapsRequired( maxTaps );
-
-  DALI_TEST_EQUALS( minTaps, detector.GetMinimumTapsRequired(), TEST_LOCATION );
-  DALI_TEST_EQUALS( maxTaps, detector.GetMaximumTapsRequired(), TEST_LOCATION );
-
-  // Attach an actor and change the required touches
-
-  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();
-
-  SignalData data;
-  GestureReceivedFunctor functor(data);
-
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Ensure signal is emitted if minimum taps received
-  application.ProcessEvent(GenerateTap(Gesture::Possible, minTaps, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, minTaps, 1u, Vector2(50.0f, 50.0f)));
-  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
-  DALI_TEST_EQUALS( minTaps, data.receivedGesture.numberOfTaps, TEST_LOCATION );
-  data.Reset();
-
-  // Ensure signal is emitted if maximum taps received
-  application.ProcessEvent(GenerateTap(Gesture::Possible, maxTaps, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, maxTaps, 1u, Vector2(50.0f, 50.0f)));
-  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
-  DALI_TEST_EQUALS( maxTaps, data.receivedGesture.numberOfTaps, TEST_LOCATION );
-  data.Reset();
-
-  // Ensure signal is NOT emitted if outside the range
-  application.ProcessEvent(GenerateTap(Gesture::Possible, minTaps - 1, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, minTaps - 1, 1u, Vector2(50.0f, 50.0f)));
-  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
-  data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, maxTaps + 1, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, maxTaps + 1, 1u, Vector2(50.0f, 50.0f)));
-  DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
-  data.Reset();
-
-  TestGestureManager& gestureManager = application.GetGestureManager();
-  gestureManager.Initialize();
-
-  detector.SetMinimumTapsRequired(4);
-
-  // Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-  // Reset values
-  gestureManager.Initialize();
-
-  detector.SetMaximumTapsRequired(maxTaps);
-
-  // Gesture detection should NOT have been updated
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-  // Reset values
-  gestureManager.Initialize();
-
-  // Create a second gesture detector that requires even less maximum touches
-  TapGestureDetector secondDetector = TapGestureDetector::New();
-  secondDetector.Attach(actor);
-
-  // Gesture detection should have been updated
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-  // Reset values
-  gestureManager.Initialize();
-
-  // Delete the second detector so that our detection is updated again
-  secondDetector.Reset();
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
-  // Set the minimum to be greater than the maximum, should Assert
-  try
-  {
-    detector.SetMinimumTapsRequired( maxTaps );
-    detector.SetMaximumTapsRequired( minTaps );
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch ( DaliException& e )
-  {
-    DALI_TEST_CHECK( true );
-  }
-
-  END_TEST;
-}
-
 int UtcDaliTapGestureSetTapsRequiredMinMaxCheck(void)
 {
   TestApplication application;
@@ -431,8 +299,7 @@ int UtcDaliTapGestureSignalReceptionNegative(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Do a tap outside actor's area
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(112.0f, 112.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(112.0f, 112.0f)));
+  TestGenerateTap( application, 112.0f, 112.0f, 100 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -458,8 +325,7 @@ int UtcDaliTapGestureSignalReceptionPositive(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Do a tap inside actor's area
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 50.0f)));
+  TestGenerateTap( application, 50.0f, 50.0f, 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTaps, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
@@ -488,8 +354,7 @@ int UtcDaliTapGestureSignalReceptionDetach(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Start tap within the actor's area
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(20.0f, 20.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(20.0f, 20.0f)));
+  TestGenerateTap( application, 20.0f, 20.0f, 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTaps, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
@@ -497,8 +362,7 @@ int UtcDaliTapGestureSignalReceptionDetach(void)
 
   // repeat the tap within the actor's area - we should still receive the signal
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 50.0f)));
+  TestGenerateTap( application, 50.0f, 50.0f, 700 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTaps, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
@@ -509,11 +373,9 @@ int UtcDaliTapGestureSignalReceptionDetach(void)
 
   // Ensure we are no longer signalled
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(20.0f, 20.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(20.0f, 20.0f)));
+  TestGenerateTap( application, 20.0f, 20.0f, 1300 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 50.0f)));
+  TestGenerateTap( application, 50.0f, 50.0f, 1900 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -542,8 +404,7 @@ int UtcDaliTapGestureSignalReceptionActorDestroyedWhileTapping(void)
     detector.Attach(actor);
 
     // Start tap within the actor's area
-    application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(20.0f, 20.0f)));
-    application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(20.0f, 20.0f)));
+    TestGenerateTap( application, 20.0f, 20.0f, 100 );
     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
     // Remove the actor from stage and reset the data
@@ -557,8 +418,7 @@ int UtcDaliTapGestureSignalReceptionActorDestroyedWhileTapping(void)
   // Actor should now have been destroyed
 
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(20.0f, 20.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(20.0f, 20.0f)));
+  TestGenerateTap( application, 20.0f, 20.0f, 700 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -584,8 +444,7 @@ int UtcDaliTapGestureSignalReceptionRotatedActor(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do tap, only check finished value
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(5.0f, 5.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(5.0f, 5.0f)));
+  TestGenerateTap( application, 5.0f, 5.0f, 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTaps, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
@@ -598,8 +457,7 @@ int UtcDaliTapGestureSignalReceptionRotatedActor(void)
 
   // Do tap, should still receive event
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(5.0f, 5.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(5.0f, 5.0f)));
+  TestGenerateTap( application, 5.0f, 5.0f, 700 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTaps, TEST_LOCATION);
   DALI_TEST_EQUALS(1u, data.receivedGesture.numberOfTouches, TEST_LOCATION);
@@ -612,8 +470,7 @@ int UtcDaliTapGestureSignalReceptionRotatedActor(void)
 
   // Do tap, inside the actor's area (area if it is not rotated), Should not receive the event
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(70.0f, 70.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(70.0f, 70.0f)));
+  TestGenerateTap( application, 70.0f, 70.0f, 1300 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -652,8 +509,7 @@ int UtcDaliTapGestureSignalReceptionChildHit(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Do tap - hits child area but parent should still receive it
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 50.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 50.0f)));
+  TestGenerateTap( application, 50.0f, 50.0f, 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, parent == data.tappedActor, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.screenPoint, 0.01f, TEST_LOCATION);
@@ -665,8 +521,7 @@ int UtcDaliTapGestureSignalReceptionChildHit(void)
 
   // Do an entire tap, only check finished value
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(51.0f, 51.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(51.0f, 51.0f)));
+  TestGenerateTap( application, 51.0f, 51.0f, 700 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, child == data.tappedActor, TEST_LOCATION);
   DALI_TEST_EQUALS(Vector2(51.0f, 51.0f), data.receivedGesture.screenPoint, 0.01f, TEST_LOCATION);
@@ -701,15 +556,13 @@ int UtcDaliTapGestureSignalReceptionAttachDetachMany(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Tap within second actor's area
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(120.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(120.0f, 10.0f)));
+  TestGenerateTap( application, 120.0f, 10.0f, 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
 
   // Tap within first actor's area
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(20.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(20.0f, 10.0f)));
+  TestGenerateTap( application, 20.0f, 10.0f, 700 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
 
@@ -718,14 +571,12 @@ int UtcDaliTapGestureSignalReceptionAttachDetachMany(void)
 
   // second actor shouldn't receive event
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(120.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(120.0f, 10.0f)));
+  TestGenerateTap( application, 120.0f, 10.0f, 1300 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // first actor should continue receiving event
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(20.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(20.0f, 10.0f)));
+  TestGenerateTap( application, 20.0f, 10.0f, 1900 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -751,8 +602,7 @@ int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
   detector.DetectedSignal().Connect(&application, functor);
 
   // Tap in actor's area
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateTap( application, 50.0f, 10.0f, 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
 
   // Actor become invisible - actor should not receive the next pan
@@ -764,8 +614,7 @@ int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
 
   // Tap in the same area, shouldn't receive event
   data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateTap( application, 50.0f, 10.0f, 700 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -773,7 +622,6 @@ int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
 int UtcDaliTapGestureSignalReceptionMultipleGestureDetectors(void)
 {
   TestApplication application;
-  Dali::TestGestureManager& gestureManager = application.GetGestureManager();
 
   Actor first = Actor::New();
   first.SetSize(100.0f, 100.0f);
@@ -799,50 +647,36 @@ int UtcDaliTapGestureSignalReceptionMultipleGestureDetectors(void)
 
   // secondDetector is scoped
   {
-    // Reset gestureManager statistics
-    gestureManager.Initialize();
-
     TapGestureDetector secondDetector = TapGestureDetector::New( 2 );
     secondDetector.Attach(second);
     secondDetector.DetectedSignal().Connect(&application, functor);
 
-    DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-    DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-    DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
-
     // Tap within second actor's area
-    application.ProcessEvent(GenerateTap(Gesture::Possible, 2u, 1u, Vector2(150.0f, 10.0f)));
-    application.ProcessEvent(GenerateTap(Gesture::Started, 2u, 1u, Vector2(150.0f, 10.0f)));
+    TestGenerateTap( application, 150.0f, 10.0f, 100 );
+    TestGenerateTap( application, 150.0f, 10.0f, 200 );
+
     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
     DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
 
     // Tap continues as single touch gesture - we should not receive any gesture
     data.Reset();
-    application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(150.0f, 10.0f)));
-    application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(150.0f, 10.0f)));
+    TestGenerateTap( application, 150.0f, 10.0f, 800 );
     DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
     // Single touch tap starts - first actor should be panned
     data.Reset();
-    application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-    application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+    TestGenerateTap( application, 50.0f, 10.0f, 1400 );
     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
     DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
 
     // Pan changes to double-touch - we shouldn't receive event
     data.Reset();
-    application.ProcessEvent(GenerateTap(Gesture::Possible, 2u, 2u, Vector2(50.0f, 10.0f)));
-    application.ProcessEvent(GenerateTap(Gesture::Started, 2u, 2u, Vector2(50.0f, 10.0f)));
-    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
-    // Reset gesture manager statistics
-    gestureManager.Initialize();
+    TestGenerateTwoPointTap( application, 50.0f, 10.0f, 60.0f, 20.0f, 2000 );
+
+    DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   }
 
-  // secondDetector has now been deleted.  Gesture detection should have been updated only
-  DALI_TEST_EQUALS(true, gestureManager.WasCalled(TestGestureManager::UpdateType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::RegisterType), TEST_LOCATION);
-  DALI_TEST_EQUALS(false, gestureManager.WasCalled(TestGestureManager::UnregisterType), TEST_LOCATION);
   END_TEST;
 }
 
@@ -874,8 +708,7 @@ int UtcDaliTapGestureSignalReceptionMultipleDetectorsOnActor(void)
   secondDetector.DetectedSignal().Connect(&application, secondFunctor);
 
   // Tap in actor's area - both detector's functors should be called
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateTap( application, 50.0f, 10.0f, 100 );
   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
   END_TEST;
@@ -902,7 +735,7 @@ int UtcDaliTapGestureSignalReceptionDifferentPossible(void)
   detector.DetectedSignal().Connect( &application, functor );
 
   // Gesture possible in actor's area.
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestStartLongPress( application, 50.0f, 10.0f, 100 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Move actor somewhere else
@@ -913,11 +746,11 @@ int UtcDaliTapGestureSignalReceptionDifferentPossible(void)
   application.Render();
 
   // Emit Started event, we should not receive the tap.
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestEndPan( application, Vector2(50.0f, 10.0f), 120 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Tap possible in empty area.
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestStartLongPress( application, 50.0f, 10.0f, 700 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Move actor in to the tap position.
@@ -928,115 +761,15 @@ int UtcDaliTapGestureSignalReceptionDifferentPossible(void)
   application.Render();
 
   // Emit Started event, we should not receive the tap.
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestEndPan( application, Vector2(50.0f, 10.0f), 720 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   // Normal tap in actor's area for completeness.
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateTap( application, 50.0f, 10.0f, 1300 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliTapGestureEmitIncorrectStateClear(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  TapGestureDetector detector = TapGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Try a Clear state
-  try
-  {
-    application.ProcessEvent(GenerateTap(Gesture::Clear, 1u, 1u, Vector2(50.0f, 10.0f)));
-    tet_result(TET_FAIL);
-  }
-  catch ( Dali::DaliException& e )
-  {
-    DALI_TEST_ASSERT( e, "Incorrect state", TEST_LOCATION );
-  }
-  END_TEST;
-}
-
-int UtcDaliTapGestureEmitIncorrectStateContinuing(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  TapGestureDetector detector = TapGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Try a Continuing state
-  try
-  {
-    application.ProcessEvent(GenerateTap(Gesture::Continuing, 1u, 1u, Vector2(50.0f, 10.0f)));
-    tet_result(TET_FAIL);
-  }
-  catch ( Dali::DaliException& e )
-  {
-    DALI_TEST_ASSERT( e, "Incorrect state", TEST_LOCATION );
-  }
-  END_TEST;
-}
-
-int UtcDaliTapGestureEmitIncorrectStateFinished(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  TapGestureDetector detector = TapGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Try a Finished state
-  try
-  {
-    application.ProcessEvent(GenerateTap(Gesture::Finished, 1u, 1u, Vector2(50.0f, 10.0f)));
-    tet_result(TET_FAIL);
-  }
-  catch ( Dali::DaliException& e )
-  {
-    DALI_TEST_ASSERT( e, "Incorrect state", TEST_LOCATION );
-  }
-  END_TEST;
-}
-
 int UtcDaliTapGestureActorUnstaged(void)
 {
   TestApplication application;
@@ -1057,80 +790,12 @@ int UtcDaliTapGestureActorUnstaged(void)
   detector.Attach(actor);
   detector.DetectedSignal().Connect( &application, functor );
 
-  // Tap in Actor's area, actor removed in signal handler, should be handled gracefully.
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateTap( application, 50.0f, 10.0f, 100 );
   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
   tet_result( TET_PASS ); // If we get here, then the actor removal on signal handler was handled gracefully.
   END_TEST;
 }
 
-int UtcDaliTapGestureRepeatedState(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  TapGestureDetector detector = TapGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Emit two possibles
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-  // Send a couple of Started states, only first one should be received.
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
-  data.Reset();
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-
-  // Send a couple of cancelled states, no reception
-  application.ProcessEvent(GenerateTap(Gesture::Cancelled, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Cancelled, 1u, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  END_TEST;
-}
-
-int UtcDaliTapGesturePossibleCancelled(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();
-
-  // Attach actor to detector
-  SignalData data;
-  GestureReceivedFunctor functor( data );
-  TapGestureDetector detector = TapGestureDetector::New();
-  detector.Attach(actor);
-  detector.DetectedSignal().Connect( &application, functor );
-
-  // Emit a possible and then a cancelled, no reception
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Cancelled, 1u, 1u, Vector2(50.0f, 10.0f)));
-  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
-  END_TEST;
-}
-
 int UtcDaliTapGestureDetectorRemovedWhilePossible(void)
 {
   TestApplication application;
@@ -1151,12 +816,12 @@ int UtcDaliTapGestureDetectorRemovedWhilePossible(void)
   detector.Attach(actor);
   detector.DetectedSignal().Connect( &application, functor );
 
-  // Emit a possible
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
+  // Emit a possible - Down press, as emitted by long press function
+  TestStartLongPress( application, 50.0f, 10.0f, 100 );
 
   // Detach actor and send a Started state, no signal.
   detector.DetachAll();
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestEndPan( application, Vector2(50.0f, 10.0f), 120 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -1181,8 +846,8 @@ int UtcDaliTapGestureActorRemovedWhilePossible(void)
   detector.Attach(actor);
   detector.DetectedSignal().Connect( &application, functor );
 
-  // Emit a possible
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
+  // Emit a possible - Down press, as emitted by long press function
+  TestStartLongPress( application, 50.0f, 10.0f, 100 );
 
   // Remove, render and delete actor
   Stage::GetCurrent().Remove(actor);
@@ -1190,8 +855,8 @@ int UtcDaliTapGestureActorRemovedWhilePossible(void)
   application.Render();
   actor.Reset();
 
-  // Send a Started state, no signal.
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  // Send a Started state, no signal - Up motion as provided by end pan function
+  TestEndPan( application, Vector2(50.0f, 10.0f), 120 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -1223,11 +888,8 @@ int UtcDaliTapGestureLayerConsumesTouch(void)
   application.SendNotification();
   application.Render();
 
-  Vector2 screenCoords( 50.0f, 50.0f );
-
   // Emit signals, should receive
-  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, screenCoords ) );
-  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, screenCoords ) );
+  TestGenerateTap( application, 50.0f, 50.0f, 100 );
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
@@ -1239,8 +901,7 @@ int UtcDaliTapGestureLayerConsumesTouch(void)
   application.Render();
 
   // Emit the same signals again, should not receive
-  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, screenCoords ) );
-  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, screenCoords ) );
+  TestGenerateTap( application, 50.0f, 50.0f, 700 );
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
diff --git a/automated-tests/src/dali/utc-Dali-TapGestureRecognizer.cpp b/automated-tests/src/dali/utc-Dali-TapGestureRecognizer.cpp
new file mode 100644 (file)
index 0000000..2576fb8
--- /dev/null
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#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/render-task-list-integ.h>
+#include <dali/internal/event/events/tap-gesture-event.h>
+#include <dali-test-suite-utils.h>
+#include <test-touch-utils.h>
+
+using namespace Dali;
+
+///////////////////////////////////////////////////////////////////////////////
+namespace
+{
+
+struct SignalData
+{
+  SignalData()
+  : functorCalled(false),
+    voidFunctorCalled(false),
+    receivedGesture()
+  {}
+
+  void Reset()
+  {
+    functorCalled = false;
+    voidFunctorCalled = false;
+
+    receivedGesture.state = Gesture::Started;
+
+    tappedActor.Reset();
+  }
+
+  bool functorCalled;
+  bool voidFunctorCalled;
+  TapGesture receivedGesture;
+  Actor tappedActor;
+};
+
+// Functor that sets the data when called
+struct GestureReceivedFunctor
+{
+  GestureReceivedFunctor(SignalData& data) : signalData(data) { }
+
+  void operator()(Actor actor, const TapGesture& tap)
+  {
+    signalData.functorCalled = true;
+    signalData.receivedGesture = tap;
+    signalData.tappedActor = actor;
+  }
+
+  void operator()()
+  {
+    signalData.voidFunctorCalled = true;
+  }
+
+  SignalData& signalData;
+};
+
+
+Integration::TouchEvent GenerateSingleTouch( PointState::Type state, const Vector2& screenPosition, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( state );
+  point.SetScreenPosition( screenPosition );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+Integration::TouchEvent GenerateDoubleTouch( PointState::Type state, const Vector2& screenPositionA, const Vector2& screenPositionB, uint32_t time )
+{
+  Integration::TouchEvent touchEvent;
+  Integration::Point point;
+  point.SetState( state );
+  point.SetScreenPosition( screenPositionA );
+  point.SetDeviceClass( Device::Class::TOUCH );
+  point.SetDeviceSubclass( Device::Subclass::NONE );
+  touchEvent.points.push_back( point );
+  point.SetScreenPosition( screenPositionB );
+  touchEvent.points.push_back( point );
+  touchEvent.time = time;
+  return touchEvent;
+}
+
+
+} // anon namespace
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+int UtcDaliTapGestureRecognizerBasic(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerGapTooLong(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 651 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerInterrupted(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::INTERRUPTED, Vector2( 20.0f, 20.0f ), 175 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerMoveTooFar(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 50.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerStartDouble(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), Vector2( 25.0f, 25.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerEndDouble(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New();
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), Vector2( 25.0f, 25.0f ), 200 ) );
+
+  application.ProcessEvent( GenerateDoubleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), Vector2( 25.0f, 25.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerDoubleTap(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 250 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 300 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerDoubleTapMoveTooFar(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 50.0f ), 250 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 50.0f ), 300 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 50.0f, 50.0f ), 450 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 50.0f, 50.0f ), 500 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 50.0f, 50.0f ), 550 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 50.0f, 50.0f ), 600 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerDoubleTapWaitTooLong(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New(2);
+
+  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();
+
+  detector.Attach(actor);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 650 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 750 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 50.0f, 50.0f ), 950 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 50.0f, 50.0f ), 1000 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 50.0f, 50.0f ), 1050 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 50.0f, 50.0f ), 1000 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTapGestureRecognizerMultipleDetectors(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetSize(100.0f, 100.0f);
+  actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(actor);
+
+  Actor actor2 = Actor::New();
+  actor2.SetSize(100.0f, 100.0f);
+  actor2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  actor2.SetX(100.0f);
+  Stage::GetCurrent().Add(actor2);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  TapGestureDetector detector = TapGestureDetector::New();
+  detector.Attach(actor);
+
+  TapGestureDetector detector2 = TapGestureDetector::New(2);
+  detector2.Attach(actor2);
+
+  SignalData data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  SignalData data2;
+  GestureReceivedFunctor functor2(data2);
+  detector2.DetectedSignal().Connect(&application, functor2);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, actor == data.tappedActor, TEST_LOCATION);
+  data.Reset();
+  DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 120.0f, 20.0f ), 250 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 120.0f, 20.0f ), 300 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 120.0f, 20.0f ), 350 ) );
+
+  application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 120.0f, 20.0f ), 400 ) );
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, data2.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
index e9178c9..fe65d5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/public-api/dali-core.h>
 #include <dali-test-suite-utils.h>
 #include <dali/internal/event/common/type-info-impl.h>
-#include <dali/integration-api/events/long-press-gesture-event.h>
-#include <dali/integration-api/events/pan-gesture-event.h>
-#include <dali/integration-api/events/pinch-gesture-event.h>
-#include <dali/integration-api/events/tap-gesture-event.h>
 #include <dali/integration-api/events/touch-event-integ.h>
 #include <dali/integration-api/events/hover-event-integ.h>
 
@@ -82,70 +78,6 @@ struct GestureReceivedFunctor
   SignalData& signalData;
 };
 
-// Generate a LongPressGestureEvent to send to Core
-Integration::LongPressGestureEvent GenerateLongPress(
-    Gesture::State state,
-    unsigned int numberOfTouches,
-    Vector2 point)
-{
-  Integration::LongPressGestureEvent longPress( state );
-
-  longPress.numberOfTouches = numberOfTouches;
-  longPress.point = point;
-
-  return longPress;
-}
-
-// Generate a PanGestureEvent to send to Core
-Integration::PanGestureEvent GeneratePan(
-    Gesture::State state,
-    Vector2 previousPosition,
-    Vector2 currentPosition,
-    unsigned long timeDelta,
-    unsigned int numberOfTouches = 1,
-    unsigned int time = 1u)
-{
-  Integration::PanGestureEvent pan(state);
-
-  pan.previousPosition = previousPosition;
-  pan.currentPosition = currentPosition;
-  pan.timeDelta = timeDelta;
-  pan.numberOfTouches = numberOfTouches;
-  pan.time = time;
-
-  return pan;
-}
-// Generate a PinchGestureEvent to send to Core
-Integration::PinchGestureEvent GeneratePinch(
-    Gesture::State state,
-    float scale,
-    float speed,
-    Vector2 centerpoint)
-{
-  Integration::PinchGestureEvent pinch(state);
-
-  pinch.scale = scale;
-  pinch.speed = speed;
-  pinch.centerPoint = centerpoint;
-
-  return pinch;
-}
-// Generate a TapGestureEvent to send to Core
-Integration::TapGestureEvent GenerateTap(
-    Gesture::State state,
-    unsigned int numberOfTaps,
-    unsigned int numberOfTouches,
-    Vector2 point)
-{
-  Integration::TapGestureEvent tap( state );
-
-  tap.numberOfTaps = numberOfTaps;
-  tap.numberOfTouches = numberOfTouches;
-  tap.point = point;
-
-  return tap;
-}
-
 //
 // Create function as Init function called
 //
@@ -2158,9 +2090,9 @@ int UtcDaliLongPressGestureDetectorTypeRegistry(void)
   application.Render();
 
   // Emit gesture
-  application.ProcessEvent(GenerateLongPress(Gesture::Possible, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Started, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateLongPress(Gesture::Finished, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateLongPress( application, 50.0f, 10.0f );
+  TestEndLongPress( application, 50.0f, 10.0f );
+
   DALI_TEST_EQUALS(true, data.voidFunctorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -2196,9 +2128,7 @@ int UtcDaliPanGestureDetectorTypeRegistry(void)
   application.Render();
 
   // Emit gesture
-  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
-  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(10.0f, 20.0f), Vector2(20.0f, 20.0f), 10));
+  TestGenerateMiniPan( application );
   DALI_TEST_EQUALS(true, data.voidFunctorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -2234,7 +2164,8 @@ int UtcDaliPinchGestureDetectorTypeRegistry(void)
   application.Render();
 
   // Emit gesture
-  application.ProcessEvent(GeneratePinch(Gesture::Started, 10.0f, 50.0f, Vector2(20.0f, 10.0f)));
+  TestGeneratePinch( application );
+
   DALI_TEST_EQUALS(true, data.voidFunctorCalled, TEST_LOCATION);
   END_TEST;
 }
@@ -2270,8 +2201,8 @@ int UtcDaliTapGestureDetectorTypeRegistry(void)
   application.Render();
 
   // Emit gesture
-  application.ProcessEvent(GenerateTap(Gesture::Possible, 1u, 1u, Vector2(50.0f, 10.0f)));
-  application.ProcessEvent(GenerateTap(Gesture::Started, 1u, 1u, Vector2(50.0f, 10.0f)));
+  TestGenerateTap( application, 50.0, 10.0, 100 );
+
   DALI_TEST_EQUALS(true, data.voidFunctorCalled, TEST_LOCATION);
   END_TEST;
 }
index 7e4630c..d66ff9f 100644 (file)
@@ -136,7 +136,6 @@ linker_test_SOURCES = linker-test.cpp  \
     ../../../automated-tests/src/dali/dali-test-suite-utils/test-render-controller.cpp \
     ../../../automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp \
     ../../../automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp \
-    ../../../automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.cpp \
     ../../../automated-tests/src/dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp \
     ../../../automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp
 
index 7b8e613..c205870 100644 (file)
@@ -11,16 +11,11 @@ SET(SOURCES ${SOURCES}
   ${CMAKE_CURRENT_SOURCE_DIR}/render-task-list-integ.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/scene.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/events/event.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/events/hover-event-integ.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/events/key-event-integ.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/long-press-gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/events/wheel-event-integ.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/events/multi-point-event-integ.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/pan-gesture-event.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/pinch-gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/events/point.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/tap-gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/events/touch-event-combiner.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/events/touch-event-integ.cpp
   PARENT_SCOPE )
@@ -39,7 +34,6 @@ SET(INTEGRATION_API_HEADERS
   ${CMAKE_CURRENT_SOURCE_DIR}/gl-abstraction.h
   ${CMAKE_CURRENT_SOURCE_DIR}/gl-defines.h
   ${CMAKE_CURRENT_SOURCE_DIR}/gl-sync-abstraction.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/gesture-manager.h
   ${CMAKE_CURRENT_SOURCE_DIR}/render-controller.h
   ${CMAKE_CURRENT_SOURCE_DIR}/platform-abstraction.h
   ${CMAKE_CURRENT_SOURCE_DIR}/processor-interface.h
@@ -48,17 +42,11 @@ SET(INTEGRATION_API_HEADERS
   ${CMAKE_CURRENT_SOURCE_DIR}/scene.h
   ${CMAKE_CURRENT_SOURCE_DIR}/render-surface.h
   ${CMAKE_CURRENT_SOURCE_DIR}/events/event.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/gesture-event.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/gesture-requests.h
   ${CMAKE_CURRENT_SOURCE_DIR}/events/hover-event-integ.h
   ${CMAKE_CURRENT_SOURCE_DIR}/events/key-event-integ.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/long-press-gesture-event.h
   ${CMAKE_CURRENT_SOURCE_DIR}/events/wheel-event-integ.h
   ${CMAKE_CURRENT_SOURCE_DIR}/events/multi-point-event-integ.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/pan-gesture-event.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/pinch-gesture-event.h
   ${CMAKE_CURRENT_SOURCE_DIR}/events/point.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/events/tap-gesture-event.h
   ${CMAKE_CURRENT_SOURCE_DIR}/events/touch-event-combiner.h
   ${CMAKE_CURRENT_SOURCE_DIR}/events/touch-event-integ.h
 
index b14df7c..8c27976 100644 (file)
@@ -38,7 +38,6 @@ Core* Core::New( RenderController& renderController,
                  PlatformAbstraction& platformAbstraction,
                  GlAbstraction& glAbstraction,
                  GlSyncAbstraction& glSyncAbstraction,
-                 GestureManager& gestureManager,
                  ResourcePolicy::DataRetention policy,
                  RenderToFrameBuffer renderToFboEnabled,
                  DepthBufferAvailable depthBufferAvailable,
@@ -49,7 +48,6 @@ Core* Core::New( RenderController& renderController,
                                         platformAbstraction,
                                         glAbstraction,
                                         glSyncAbstraction,
-                                        gestureManager,
                                         policy,
                                         renderToFboEnabled,
                                         depthBufferAvailable,
index 45d7582..df3bec0 100644 (file)
@@ -240,7 +240,6 @@ public:
                     PlatformAbstraction& platformAbstraction,
                     GlAbstraction& glAbstraction,
                     GlSyncAbstraction& glSyncAbstraction,
-                    GestureManager& gestureManager,
                     ResourcePolicy::DataRetention policy,
                     RenderToFrameBuffer renderToFboEnabled,
                     DepthBufferAvailable depthBufferAvailable,
index 860011e..b745a30 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_INTEGRATION_EVENT_H__
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -46,7 +46,6 @@ struct DALI_CORE_API Event
   {
     Touch,         ///< A touch event, when the user interacts with the screen.
     Key,           ///< A key pressed event, from the virtual or external keyboard.
-    Gesture,       ///< A Gesture event has been detected.
     Wheel,         ///< A wheel event, when the wheel is being rolled from an external mouse.
     Hover          ///< A hover event, when the user hovers above the screen.
   };
index 4b846a8..50c62ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ HoverEvent::HoverEvent()
 {
 }
 
-HoverEvent::HoverEvent( unsigned long time )
+HoverEvent::HoverEvent( uint32_t time )
 : MultiPointEvent( Hover, time )
 {
 }
index 0010b25..39c0d29 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_HOVER_EVENT_H__
-#define __DALI_INTEGRATION_HOVER_EVENT_H__
+#ifndef DALI_INTEGRATION_HOVER_EVENT_H
+#define DALI_INTEGRATION_HOVER_EVENT_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ struct DALI_CORE_API HoverEvent : public MultiPointEvent
    * Constructor
    * @param[in]  time  The time the event occurred.
    */
-  HoverEvent(unsigned long time);
+  HoverEvent(uint32_t time);
 
   /**
    * Virtual destructor
@@ -59,4 +59,4 @@ struct DALI_CORE_API HoverEvent : public MultiPointEvent
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_HOVER_EVENT_H__
+#endif // DALI_INTEGRATION_HOVER_EVENT_H
index 099bb3e..b0f2d6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ MultiPointEvent::MultiPointEvent( Type eventType )
 {
 }
 
-MultiPointEvent::MultiPointEvent( Type eventType, unsigned long time )
+MultiPointEvent::MultiPointEvent( Type eventType, uint32_t time )
 : Event( eventType ),
   time( time )
 {
index 7dec1be..a3331d2 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_MULTI_POINT_EVENT_H__
-#define __DALI_INTEGRATION_MULTI_POINT_EVENT_H__
+#ifndef DALI_INTEGRATION_MULTI_POINT_EVENT_H
+#define DALI_INTEGRATION_MULTI_POINT_EVENT_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -59,7 +59,7 @@ protected:
    * Constructor
    * @param[in]  time  The time the event occurred.
    */
-  MultiPointEvent(Type eventType, unsigned long time);
+  MultiPointEvent(Type eventType, uint32_t time);
 
 public:
 
@@ -73,7 +73,7 @@ public:
   /**
    * @brief The time
    */
-  unsigned long time;
+  uint32_t time;
 
   // Convenience Methods
 
@@ -106,4 +106,4 @@ public:
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_MULTI_POINT_EVENT_H__
+#endif // DALI_INTEGRATION_MULTI_POINT_EVENT_H
index 5e7a649..768b741 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ struct TouchEventCombiner::PointInfo
    * @param[in]  touchPoint  The point to add.
    * @param[in]  pointTime   The time of the point event.
    */
-  PointInfo( const Point& touchPoint, unsigned long pointTime )
+  PointInfo( const Point& touchPoint, uint32_t pointTime )
   : point( touchPoint ),
     time( pointTime )
   {
@@ -57,7 +57,7 @@ struct TouchEventCombiner::PointInfo
   // Data
 
   Point point;        ///< The point.
-  unsigned long time; ///< The time the point event took place.
+  uint32_t time; ///< The time the point event took place.
 };
 
 TouchEventCombiner::TouchEventCombiner()
@@ -66,14 +66,14 @@ TouchEventCombiner::TouchEventCombiner()
 {
 }
 
-TouchEventCombiner::TouchEventCombiner( unsigned long minMotionTime, float minMotionXDistance, float minMotionYDistance )
+TouchEventCombiner::TouchEventCombiner( uint32_t minMotionTime, float minMotionXDistance, float minMotionYDistance )
 : mMinMotionTime( minMotionTime ),
   mMinMotionDistance( minMotionXDistance, minMotionYDistance )
 {
   DALI_ASSERT_ALWAYS( minMotionXDistance >= 0.0f && minMotionYDistance >= 0.0f && "Negative values not allowed\n" );
 }
 
-TouchEventCombiner::TouchEventCombiner( unsigned long minMotionTime, Vector2 minMotionDistance )
+TouchEventCombiner::TouchEventCombiner( uint32_t minMotionTime, Vector2 minMotionDistance )
 : mMinMotionTime( minMotionTime ),
   mMinMotionDistance( minMotionDistance )
 {
@@ -84,7 +84,7 @@ TouchEventCombiner::~TouchEventCombiner()
 {
 }
 
-TouchEventCombiner::EventDispatchType TouchEventCombiner::GetNextTouchEvent( const Point& point, unsigned long time, TouchEvent& touchEvent, HoverEvent& hoverEvent )
+TouchEventCombiner::EventDispatchType TouchEventCombiner::GetNextTouchEvent( const Point& point, uint32_t time, TouchEvent& touchEvent, HoverEvent& hoverEvent )
 {
   TouchEventCombiner::EventDispatchType dispatchEvent( TouchEventCombiner::DispatchNone );
   const PointState::Type state = point.GetState();
@@ -210,7 +210,7 @@ TouchEventCombiner::EventDispatchType TouchEventCombiner::GetNextTouchEvent( con
         {
           if ( deviceId == iter->point.GetDeviceId() )
           {
-            unsigned long timeDiff( time - iter->time );
+            uint32_t timeDiff( time - iter->time );
 
             if ( timeDiff < mMinMotionTime )
             {
@@ -266,7 +266,7 @@ TouchEventCombiner::EventDispatchType TouchEventCombiner::GetNextTouchEvent( con
         {
           if ( iter->point.GetDeviceId() == deviceId )
           {
-            unsigned long timeDiff( time - iter->time );
+            uint32_t timeDiff( time - iter->time );
 
             if ( timeDiff < mMinMotionTime )
             {
@@ -343,7 +343,7 @@ TouchEventCombiner::EventDispatchType TouchEventCombiner::GetNextTouchEvent( con
   return dispatchEvent;
 }
 
-void TouchEventCombiner::SetMinimumMotionTimeThreshold( unsigned long minTime )
+void TouchEventCombiner::SetMinimumMotionTimeThreshold( uint32_t minTime )
 {
   mMinMotionTime = minTime;
 }
index be6bf70..2849380 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_TOUCH_EVENT_COMBINER_H__
-#define __DALI_INTEGRATION_TOUCH_EVENT_COMBINER_H__
+#ifndef DALI_INTEGRATION_TOUCH_EVENT_COMBINER_H
+#define DALI_INTEGRATION_TOUCH_EVENT_COMBINER_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -74,7 +74,7 @@ public:
    * @param[in]  minMotionYDistance  The minimum distance a finger has to be moved between vertical motion events.
    * @note Will assert if any of the parameters is negative.
    */
-  TouchEventCombiner( unsigned long minMotionTime, float minMotionXDistance, float minMotionYDistance );
+  TouchEventCombiner( uint32_t minMotionTime, float minMotionXDistance, float minMotionYDistance );
 
   /**
    * Construction with parameters.
@@ -82,7 +82,7 @@ public:
    * @param[in]  minMotionDistance  A Vector2 representing the minimum distance a finger has to be moved between horizontal and vertical motion events.
    * @note Will assert if any of the parameters is negative.
    */
-  TouchEventCombiner( unsigned long minMotionTime, Vector2 minMotionDistance );
+  TouchEventCombiner( uint32_t minMotionTime, Vector2 minMotionDistance );
 
   /**
    * Non virtual destructor
@@ -105,13 +105,13 @@ public:
    *
    * @return true if the point is beyond the different thresholds set thus, should be sent to core, false otherwise.
    */
-  EventDispatchType GetNextTouchEvent( const Point& point, unsigned long time, TouchEvent& touchEvent, HoverEvent& hoverEvent );
+  EventDispatchType GetNextTouchEvent( const Point& point, uint32_t time, TouchEvent& touchEvent, HoverEvent& hoverEvent );
 
   /**
    * Sets the minimum time (in ms) that should occur between motion events.
    * @param[in]  minTime  Minimum time between motion events.
    */
-  void SetMinimumMotionTimeThreshold( unsigned long minTime );
+  void SetMinimumMotionTimeThreshold( uint32_t minTime );
 
   /**
    * Sets the minimum distance a finger has to be moved (both X and Y) between motion events.
@@ -163,7 +163,7 @@ private:
   PointInfoContainer mPressedPoints; ///< A container of touched point and time.
   PointInfoContainer mHoveredPoints; ///< A container of hovered point and time.
 
-  unsigned long mMinMotionTime; ///< The minimum time that should elapse before considering a new motion event.
+  uint32_t mMinMotionTime; ///< The minimum time that should elapse before considering a new motion event.
   Vector2 mMinMotionDistance; ///< The minimum distance in the X and Y direction before considering a new motion event.
 };
 
@@ -171,4 +171,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_TOUCH_EVENT_COMBINER_H__
+#endif // DALI_INTEGRATION_TOUCH_EVENT_COMBINER_H
index ac44731..a660660 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ TouchEvent::TouchEvent()
 {
 }
 
-TouchEvent::TouchEvent( unsigned long time )
+TouchEvent::TouchEvent( uint32_t time )
 : MultiPointEvent( Touch, time )
 {
 }
index c0982be..2d8bcd3 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_TOUCH_EVENT_H__
-#define __DALI_INTEGRATION_TOUCH_EVENT_H__
+#ifndef DALI_INTEGRATION_TOUCH_EVENT_H
+#define DALI_INTEGRATION_TOUCH_EVENT_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ struct DALI_CORE_API TouchEvent : public MultiPointEvent
    * Constructor
    * @param[in]  time  The time the event occurred.
    */
-  TouchEvent(unsigned long time);
+  TouchEvent(uint32_t time);
 
   /**
    * Virtual destructor
@@ -59,4 +59,4 @@ struct DALI_CORE_API TouchEvent : public MultiPointEvent
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_TOUCH_EVENT_H__
+#endif // DALI_INTEGRATION_TOUCH_EVENT_H
index db6517c..9ec9155 100644 (file)
@@ -11,16 +11,11 @@ platform_abstraction_src_files = \
    $(platform_abstraction_src_dir)/render-task-list-integ.cpp \
    $(platform_abstraction_src_dir)/scene.cpp \
    $(platform_abstraction_src_dir)/events/event.cpp \
-   $(platform_abstraction_src_dir)/events/gesture-event.cpp \
    $(platform_abstraction_src_dir)/events/hover-event-integ.cpp \
    $(platform_abstraction_src_dir)/events/key-event-integ.cpp \
-   $(platform_abstraction_src_dir)/events/long-press-gesture-event.cpp \
    $(platform_abstraction_src_dir)/events/wheel-event-integ.cpp \
    $(platform_abstraction_src_dir)/events/multi-point-event-integ.cpp \
-   $(platform_abstraction_src_dir)/events/pan-gesture-event.cpp \
-   $(platform_abstraction_src_dir)/events/pinch-gesture-event.cpp \
    $(platform_abstraction_src_dir)/events/point.cpp \
-   $(platform_abstraction_src_dir)/events/tap-gesture-event.cpp \
    $(platform_abstraction_src_dir)/events/touch-event-combiner.cpp \
    $(platform_abstraction_src_dir)/events/touch-event-integ.cpp
 
@@ -38,7 +33,6 @@ platform_abstraction_header_files = \
    $(platform_abstraction_src_dir)/gl-abstraction.h \
    $(platform_abstraction_src_dir)/gl-defines.h \
    $(platform_abstraction_src_dir)/gl-sync-abstraction.h \
-   $(platform_abstraction_src_dir)/gesture-manager.h \
    $(platform_abstraction_src_dir)/render-controller.h \
    $(platform_abstraction_src_dir)/platform-abstraction.h \
    $(platform_abstraction_src_dir)/processor-interface.h \
@@ -49,16 +43,10 @@ platform_abstraction_header_files = \
 
 platform_abstraction_events_header_files = \
    $(platform_abstraction_src_dir)/events/event.h \
-   $(platform_abstraction_src_dir)/events/gesture-event.h \
-   $(platform_abstraction_src_dir)/events/gesture-requests.h \
    $(platform_abstraction_src_dir)/events/hover-event-integ.h \
    $(platform_abstraction_src_dir)/events/key-event-integ.h \
-   $(platform_abstraction_src_dir)/events/long-press-gesture-event.h \
    $(platform_abstraction_src_dir)/events/wheel-event-integ.h \
    $(platform_abstraction_src_dir)/events/multi-point-event-integ.h \
-   $(platform_abstraction_src_dir)/events/pan-gesture-event.h \
-   $(platform_abstraction_src_dir)/events/pinch-gesture-event.h \
    $(platform_abstraction_src_dir)/events/point.h \
-   $(platform_abstraction_src_dir)/events/tap-gesture-event.h \
    $(platform_abstraction_src_dir)/events/touch-event-combiner.h \
    $(platform_abstraction_src_dir)/events/touch-event-integ.h
index e05619f..54eb9fb 100644 (file)
@@ -102,6 +102,24 @@ void SetPanGestureMultitapSmoothingRange( int value )
   eventProcessor.SetPanGestureMultitapSmoothingRange( value );
 }
 
+void SetPanGestureMinimumDistance( int value )
+{
+  GestureEventProcessor& eventProcessor = ThreadLocalStorage::Get().GetGestureEventProcessor();
+  eventProcessor.SetPanGestureMinimumDistance( value );
+}
+
+void SetPanGestureMinimumPanEvents( int value )
+{
+  GestureEventProcessor& eventProcessor = ThreadLocalStorage::Get().GetGestureEventProcessor();
+  eventProcessor.SetPanGestureMinimumPanEvents( value );
+}
+
+void SetPinchGestureMinimumDistance( float value )
+{
+  GestureEventProcessor& eventProcessor = ThreadLocalStorage::Get().GetGestureEventProcessor();
+  eventProcessor.SetPinchGestureMinimumDistance( value );
+}
+
 
 } // namespace Integration
 
index 6b8ce6b..464eff7 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_INPUT_OPTIONS_H__
-#define __DALI_INTEGRATION_INPUT_OPTIONS_H__
+#ifndef DALI_INTEGRATION_INPUT_OPTIONS_H
+#define DALI_INTEGRATION_INPUT_OPTIONS_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -143,9 +143,28 @@ DALI_CORE_API void SetPanGestureTwoPointAccelerationBias( float value );
  */
 DALI_CORE_API void SetPanGestureMultitapSmoothingRange( int value );
 
+/**
+ * @brief Sets the minimum distance required to start a pan gesture
+ *
+ * @param[in] value Distance to move
+ */
+DALI_CORE_API void SetPanGestureMinimumDistance( int value );
+
+/**
+ * @brief Sets the minimum number of touch events to start a pan
+ *
+ * @param[in] value Number of pan events
+ */
+DALI_CORE_API void SetPanGestureMinimumPanEvents( int value );
 
+/**
+ * @brief Sets the minimum distance required to start a pinch gesture
+ *
+ * @param[in] value Distance to move in pixels
+ */
+DALI_CORE_API void SetPinchGestureMinimumDistance( float value );
 } // namespace Integration
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_INPUT_OPTIONS_H__
+#endif // DALI_INTEGRATION_INPUT_OPTIONS_H
index 79161fb..b9187c8 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_PLATFORM_ABSTRACTION_H__
-#define __DALI_INTEGRATION_PLATFORM_ABSTRACTION_H__
+#ifndef DALI_INTEGRATION_PLATFORM_ABSTRACTION_H
+#define DALI_INTEGRATION_PLATFORM_ABSTRACTION_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
 #include <dali/integration-api/resource-types.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/signals/callback.h>
 
 namespace Dali
 {
@@ -127,6 +128,20 @@ public:
    */
   virtual bool SaveShaderBinaryFile( const std::string& filename, const uint8_t * buffer, uint32_t numBytes ) const = 0;
 
+  /**
+   * Sets a callback to occur in the future
+   * @param[in] milliseconds number of milliseconds to wait until executing the callback
+   * @param[in] callback function to call when the timer expires
+   * @result    a timer reference ID, to be used for cancelling the timer
+   */
+  virtual uint32_t StartTimer( uint32_t milliseconds, CallbackBase* callback ) = 0;
+
+  /**
+   * Cancels a running timer
+   * @param[in] timerId the ID reference returned when the timer was started
+   */
+  virtual void CancelTimer ( uint32_t timerId ) = 0;
+
 protected:
 
   /**
@@ -140,4 +155,4 @@ protected:
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_PLATFORM_ABSTRACTION_H__
+#endif // DALI_INTEGRATION_PLATFORM_ABSTRACTION_H
index 17ce42a..c6466c1 100644 (file)
@@ -48,20 +48,29 @@ SET(SOURCES ${SOURCES}
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/key-event-impl.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/key-event-processor.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/gesture-detector-impl.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/gesture-event-processor.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/gesture-processor.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/hit-test-algorithm-impl.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/hover-event-processor.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/long-press-gesture-detector-impl.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/long-press-gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/long-press-gesture-processor.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/long-press-gesture-recognizer.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/wheel-event-processor.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/multi-point-event-util.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/pan-gesture-detector-impl.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/pan-gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/pan-gesture-processor.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/pan-gesture-recognizer.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/pinch-gesture-detector-impl.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/pinch-gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/pinch-gesture-processor.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/pinch-gesture-recognizer.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/tap-gesture-detector-impl.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/tap-gesture-event.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/tap-gesture-processor.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/event/events/tap-gesture-recognizer.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/touch-data-impl.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/events/touch-event-processor.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/event/images/bitmap-packed-pixel.cpp
index 8e99503..1a09947 100644 (file)
@@ -74,7 +74,6 @@ namespace Internal
 using Integration::RenderController;
 using Integration::PlatformAbstraction;
 using Integration::GlSyncAbstraction;
-using Integration::GestureManager;
 using Integration::GlAbstraction;
 using Integration::Event;
 using Integration::UpdateStatus;
@@ -84,7 +83,6 @@ Core::Core( RenderController& renderController,
             PlatformAbstraction& platform,
             GlAbstraction& glAbstraction,
             GlSyncAbstraction& glSyncAbstraction,
-            GestureManager& gestureManager,
             ResourcePolicy::DataRetention dataRetentionPolicy,
             Integration::RenderToFrameBuffer renderToFboEnabled,
             Integration::DepthBufferAvailable depthBufferAvailable,
@@ -132,7 +130,7 @@ Core::Core( RenderController& renderController,
   // This must be called after stage is created but before stage initialization
   mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) );
 
-  mGestureEventProcessor = new GestureEventProcessor( *mUpdateManager, gestureManager, mRenderController );
+  mGestureEventProcessor = new GestureEventProcessor( *mUpdateManager, mRenderController );
 
   mShaderFactory = new ShaderFactory();
   mUpdateManager->SetShaderSaver( *mShaderFactory );
index 6e51b4a..9105f7a 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_CORE_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,7 +39,6 @@ namespace Integration
 class Processor;
 class RenderController;
 class PlatformAbstraction;
-class GestureManager;
 class GlAbstraction;
 class GlSyncAbstraction;
 class UpdateStatus;
@@ -84,7 +83,6 @@ public:
         Integration::PlatformAbstraction& platform,
         Integration::GlAbstraction& glAbstraction,
         Integration::GlSyncAbstraction& glSyncAbstraction,
-        Integration::GestureManager& gestureManager,
         ResourcePolicy::DataRetention dataRetentionPolicy,
         Integration::RenderToFrameBuffer renderToFboEnabled,
         Integration::DepthBufferAvailable depthBufferAvailable,
index 1eab332..8ce6c11 100644 (file)
@@ -31,13 +31,13 @@ namespace Internal
 
 namespace
 {
-thread_local ThreadLocalStorage* threadLocal = NULL;
+thread_local ThreadLocalStorage* threadLocal = nullptr;
 }
 
 ThreadLocalStorage::ThreadLocalStorage(Core* core)
 : mCore( core )
 {
-  DALI_ASSERT_ALWAYS( threadLocal == NULL && "Cannot create more than one ThreadLocalStorage object" );
+  DALI_ASSERT_ALWAYS( threadLocal == nullptr && "Cannot create more than one ThreadLocalStorage object" );
 
   threadLocal = this;
 }
@@ -48,7 +48,7 @@ ThreadLocalStorage::~ThreadLocalStorage()
 
 void ThreadLocalStorage::Remove()
 {
-  threadLocal = NULL;
+  threadLocal = nullptr;
 }
 
 ThreadLocalStorage& ThreadLocalStorage::Get()
@@ -61,7 +61,7 @@ ThreadLocalStorage& ThreadLocalStorage::Get()
 bool ThreadLocalStorage::Created()
 {
   // see if the TLS has been set yet
-  return (threadLocal != NULL);
+  return (threadLocal != nullptr);
 }
 
 ThreadLocalStorage* ThreadLocalStorage::GetInternal()
index d19ff67..06250ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/events/event.h>
-#include <dali/integration-api/events/gesture-event.h>
 #include <dali/integration-api/events/key-event-integ.h>
 #include <dali/integration-api/events/wheel-event-integ.h>
 #include <dali/integration-api/events/touch-event-integ.h>
 #include <dali/integration-api/events/hover-event-integ.h>
-#include <dali/integration-api/events/pinch-gesture-event.h>
-#include <dali/integration-api/events/pan-gesture-event.h>
-#include <dali/integration-api/events/tap-gesture-event.h>
-#include <dali/integration-api/events/long-press-gesture-event.h>
 #include <dali/internal/event/events/gesture-event-processor.h>
 #include <dali/internal/common/core-impl.h>
 #include <dali/internal/event/common/notification-manager.h>
@@ -46,8 +41,7 @@ namespace // unnamed namespace
 {
 
 static const std::size_t MAX_MESSAGE_SIZE = std::max( sizeof(Integration::TouchEvent),
-                                                      std::max( sizeof(Integration::KeyEvent),
-                                                                std::max( sizeof(Integration::WheelEvent), sizeof(Integration::GestureEvent) ) ) );
+                                                      std::max( sizeof(Integration::KeyEvent), sizeof(Integration::WheelEvent) ) );
 
 static const std::size_t INITIAL_MIN_CAPACITY = 4;
 
@@ -140,71 +134,6 @@ void EventProcessor::QueueEvent( const Event& event )
 
       break;
     }
-
-    case Event::Gesture:
-    {
-      QueueGestureEvent( static_cast<const Integration::GestureEvent&>(event) );
-      break;
-    }
-
-  }
-}
-
-void EventProcessor::QueueGestureEvent(const Integration::GestureEvent& event)
-{
-  switch( event.gestureType )
-  {
-    case Gesture::Pinch:
-    {
-      typedef Integration::PinchGestureEvent DerivedType;
-
-      // Reserve some memory inside the message queue
-      uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
-
-      // Construct message in the message queue memory; note that delete should not be called on the return value
-      new (slot) DerivedType( static_cast<const DerivedType&>(event) );
-
-      break;
-    }
-
-    case Gesture::Pan:
-    {
-      typedef Integration::PanGestureEvent DerivedType;
-
-      // Reserve some memory inside the message queue
-      uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
-
-      // Construct message in the message queue memory; note that delete should not be called on the return value
-      new (slot) DerivedType( static_cast<const DerivedType&>(event) );
-
-      break;
-    }
-
-    case Gesture::Tap:
-    {
-      typedef Integration::TapGestureEvent DerivedType;
-
-      // Reserve some memory inside the message queue
-      uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
-
-      // Construct message in the message queue memory; note that delete should not be called on the return value
-      new (slot) DerivedType( static_cast<const DerivedType&>(event) );
-
-      break;
-    }
-
-    case Gesture::LongPress:
-    {
-      typedef Integration::LongPressGestureEvent DerivedType;
-
-      // Reserve some memory inside the message queue
-      uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
-
-      // Construct message in the message queue memory; note that delete should not be called on the return value
-      new (slot) DerivedType( static_cast<const DerivedType&>(event) );
-
-      break;
-    }
   }
 }
 
@@ -224,6 +153,7 @@ void EventProcessor::ProcessEvents()
       case Event::Touch:
       {
         mTouchEventProcessor.ProcessTouchEvent( static_cast<const Integration::TouchEvent&>(*event) );
+        mGestureEventProcessor.ProcessTouchEvent(mScene, static_cast<const Integration::TouchEvent&>(*event));
         break;
       }
 
@@ -244,13 +174,6 @@ void EventProcessor::ProcessEvents()
         mWheelEventProcessor.ProcessWheelEvent( static_cast<const Integration::WheelEvent&>(*event) );
         break;
       }
-
-      case Event::Gesture:
-      {
-        mGestureEventProcessor.ProcessGestureEvent( mScene, static_cast<const Integration::GestureEvent&>(*event) );
-        break;
-      }
-
     }
     // Call virtual destructor explictly; since delete will not be called after placement new
     event->~Event();
index 44392b1..c9734d3 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_EVENT_PROCESSOR_H__
-#define __DALI_INTERNAL_EVENT_PROCESSOR_H__
+#ifndef DALI_INTERNAL_EVENT_PROCESSOR_H
+#define DALI_INTERNAL_EVENT_PROCESSOR_H
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@ namespace Dali
 namespace Integration
 {
 struct Event;
-struct GestureEvent;
 }
 
 namespace Internal
@@ -79,13 +78,6 @@ public:
 
 private:
 
-  /**
-   * Helper for QueueEvent()
-   */
-  void QueueGestureEvent(const Integration::GestureEvent& event);
-
-private:
-
   Scene& mScene;                                        ///< The Scene events are processed for.
   TouchEventProcessor      mTouchEventProcessor;        ///< Processes touch events.
   HoverEventProcessor      mHoverEventProcessor;        ///< Processes hover events.
@@ -103,5 +95,5 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_EVENT_PROCESSOR_H__
+#endif // DALI_INTERNAL_EVENT_PROCESSOR_H
 
index a871337..c541a7a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -43,6 +43,18 @@ GestureDetector::GestureDetector(Gesture::Type type, const SceneGraph::PropertyO
 
 GestureDetector::~GestureDetector()
 {
+  if ( !mPendingAttachActors.empty() )
+  {
+    for ( GestureDetectorActorContainer::iterator iter = mPendingAttachActors.begin(), endIter = mPendingAttachActors.end(); iter != endIter; ++iter )
+    {
+      Actor* actor( *iter );
+      actor->RemoveObserver( *this );
+      actor->GetGestureData().RemoveGestureDetector( *this );
+    }
+
+    mPendingAttachActors.clear();
+  }
+
   if ( !mAttachedActors.empty() )
   {
     for ( GestureDetectorActorContainer::iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter )
@@ -64,29 +76,88 @@ GestureDetector::~GestureDetector()
 
 void GestureDetector::Attach( Actor& actor )
 {
-  if ( !IsAttached( actor) )
+  if ( !IsAttached( actor ) )
   {
-    // Register with EventProcessor if first actor being added
-    if( mAttachedActors.empty() )
+    if( actor.OnStage() )
+    {
+      // Register with EventProcessor if first actor being added
+      if( mAttachedActors.empty() )
+      {
+        mGestureEventProcessor.AddGestureDetector( this, actor.GetScene() );
+      }
+      mAttachedActors.push_back( &actor );
+      // We need to observe the actor's destruction
+      actor.AddObserver( *this );
+      // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
+      actor.GetGestureData().AddGestureDetector( *this );
+      // Notification for derived classes
+      OnActorAttach( actor );
+    }
+    else
     {
-      mGestureEventProcessor.AddGestureDetector( this );
+      actor.AddObserver( *this );
+      // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
+      actor.GetGestureData().AddGestureDetector( *this );
+
+      mPendingAttachActors.push_back( &actor );
     }
+  }
+}
+
+void GestureDetector::SceneObjectAdded( Object& object )
+{
+  Actor& actor = dynamic_cast< Actor& >( object );
 
-    mAttachedActors.push_back( &actor );
+  // Make sure the actor has not already been attached. Can't use IsAttached() as that checks the pending list as well
+  if( find(mAttachedActors.begin(), mAttachedActors.end(), &actor) == mAttachedActors.end() )
+  {
+    GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor);
 
-    // We need to observe the actor's destruction
-    actor.AddObserver( *this );
+    if ( match != mPendingAttachActors.end() )
+    {
+      mPendingAttachActors.erase(match);
 
-    // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
-    actor.GetGestureData().AddGestureDetector( *this );
+      // Register with EventProcessor if first actor being added
+      if( mAttachedActors.empty() )
+      {
+        mGestureEventProcessor.AddGestureDetector( this, actor.GetScene() );
+      }
+      mAttachedActors.push_back( &actor );
 
-    // Notification for derived classes
-    OnActorAttach( actor );
+      // Notification for derived classes
+      OnActorAttach( actor );
+    }
+    else
+    {
+      // Actor was not in the pending list
+      DALI_ASSERT_DEBUG( false );
+    }
+  }
+  else
+  {
+    // Check if actor has been attached and is still in the pending list - this would not be correct
+    DALI_ASSERT_DEBUG( find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor) == mPendingAttachActors.end() );
   }
 }
 
 void GestureDetector::Detach(Actor& actor)
 {
+  if ( !mPendingAttachActors.empty() )
+  {
+    GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor);
+
+    if ( match != mPendingAttachActors.end() )
+    {
+      // We no longer need to observe the actor's destruction
+      actor.RemoveObserver(*this);
+
+      // Remove detector from actor-gesture-data
+      actor.GetGestureData().RemoveGestureDetector( *this );
+
+      mPendingAttachActors.erase(match);
+    }
+  }
+
   if ( !mAttachedActors.empty() )
   {
     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &actor);
@@ -119,6 +190,24 @@ void GestureDetector::Detach(Actor& actor)
 
 void GestureDetector::DetachAll()
 {
+  if ( !mPendingAttachActors.empty() )
+  {
+    GestureDetectorActorContainer pendingActors(mPendingAttachActors);
+
+    mPendingAttachActors.clear();
+
+    for ( GestureDetectorActorContainer::iterator iter = pendingActors.begin(), endIter = pendingActors.end(); iter != endIter; ++iter )
+    {
+      Actor* actor(*iter);
+
+      // We no longer need to observe the actor's destruction
+      actor->RemoveObserver(*this);
+
+      // Remove detector from actor-gesture-data
+      actor->GetGestureData().RemoveGestureDetector( *this );
+    }
+  }
+
   if ( !mAttachedActors.empty() )
   {
     GestureDetectorActorContainer attachedActors(mAttachedActors);
@@ -151,16 +240,20 @@ void GestureDetector::DetachAll()
 
 size_t GestureDetector::GetAttachedActorCount() const
 {
-  return mAttachedActors.size();
+  return mPendingAttachActors.size() + mAttachedActors.size();
 }
 
 Dali::Actor GestureDetector::GetAttachedActor(size_t index) const
 {
   Dali::Actor actor;
 
-  if( index < mAttachedActors.size() )
+  if( index < mPendingAttachActors.size() )
   {
-    actor = Dali::Actor( mAttachedActors[index] );
+    actor = Dali::Actor( mPendingAttachActors[index] );
+  }
+  else if( index < mPendingAttachActors.size() + mAttachedActors.size() )
+  {
+    actor = Dali::Actor( mAttachedActors[index - mPendingAttachActors.size()] );
   }
 
   return actor;
@@ -168,11 +261,22 @@ Dali::Actor GestureDetector::GetAttachedActor(size_t index) const
 
 bool GestureDetector::IsAttached(Actor& actor) const
 {
-  return find(mAttachedActors.begin(), mAttachedActors.end(), &actor) != mAttachedActors.end();
+  return ( find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor) != mPendingAttachActors.end() ) ||
+         ( find(mAttachedActors.begin(), mAttachedActors.end(), &actor) != mAttachedActors.end() );
 }
 
 void GestureDetector::ObjectDestroyed(Object& object)
 {
+  if ( !mPendingAttachActors.empty() )
+  {
+    GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &object);
+
+    if ( match != mPendingAttachActors.end() )
+    {
+      mPendingAttachActors.erase(match);
+    }
+  }
+
   if ( !mAttachedActors.empty() )
   {
     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &object);
index f3fc8d5..54976d6 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_GESTURE_DETECTOR_H__
-#define __DALI_INTERNAL_GESTURE_DETECTOR_H__
+#ifndef DALI_INTERNAL_GESTURE_DETECTOR_H
+#define DALI_INTERNAL_GESTURE_DETECTOR_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -104,9 +104,9 @@ public:
   }
 
   /**
-   * Checks if the specified actor is still attached.
+   * Checks if the specified actor is still attached or pending attachment.
    * @param[in]  actor  The actor to check.
-   * @return true, if the actor is attached, false otherwise.
+   * @return true, if the actor is attached or pending, false otherwise.
    */
   bool IsAttached(Actor& actor) const;
 
@@ -135,7 +135,7 @@ private:
   /**
    * @copydoc Dali::Internal::Object::Observer::SceneObjectAdded()
    */
-  virtual void SceneObjectAdded(Object& object) {}
+  virtual void SceneObjectAdded(Object& object);
 
   /**
    * @copydoc Dali::Internal::Object::Observer::SceneObjectAdded()
@@ -171,6 +171,7 @@ protected:
 
   Gesture::Type                 mType;                  ///< The gesture detector will detect this type of gesture.
   GestureDetectorActorContainer mAttachedActors;        ///< Object::Observer is used to provide weak-pointer behaviour
+  GestureDetectorActorContainer mPendingAttachActors;   ///< Object::Observer is used to provide weak-pointer behaviour
   GestureEventProcessor&        mGestureEventProcessor; ///< A reference to the gesture event processor.
 };
 
@@ -198,4 +199,4 @@ inline const Internal::GestureDetector& GetImplementation(const Dali::GestureDet
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_GESTURE_DETECTOR_H__
+#endif // DALI_INTERNAL_GESTURE_DETECTOR_H
index 07eb618..b307e6e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 // CLASS HEADER
 #include <dali/internal/event/events/gesture-event-processor.h>
 
+#if defined(DEBUG_ENABLED)
+#include <sstream>
+#endif
+
 // INTERNAL INCLUDES
-#include <dali/integration-api/events/gesture-event.h>
-#include <dali/integration-api/events/long-press-gesture-event.h>
-#include <dali/integration-api/events/pan-gesture-event.h>
-#include <dali/integration-api/events/pinch-gesture-event.h>
-#include <dali/integration-api/events/tap-gesture-event.h>
-#include <dali/integration-api/gesture-manager.h>
 #include <dali/integration-api/render-controller.h>
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/events/pinch-gesture-detector-impl.h>
 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
 #include <dali/public-api/events/pan-gesture.h>
+#include <dali/integration-api/debug.h>
+
 
 namespace Dali
 {
 
 namespace Internal
 {
-
-GestureEventProcessor::GestureEventProcessor( SceneGraph::UpdateManager& updateManager, Integration::GestureManager& gestureManager, Integration::RenderController& renderController )
-: mGestureManager( gestureManager ),
-  mLongPressGestureProcessor( gestureManager ),
-  mPanGestureProcessor( gestureManager, updateManager ),
-  mPinchGestureProcessor( gestureManager ),
-  mTapGestureProcessor( gestureManager ),
+GestureEventProcessor::GestureEventProcessor( SceneGraph::UpdateManager& updateManager, Integration::RenderController& renderController )
+: mLongPressGestureProcessor(),
+  mPanGestureProcessor( updateManager ),
+  mPinchGestureProcessor(),
+  mTapGestureProcessor(),
   mRenderController( renderController ),
-  mUpdateRequired( false )
+  mLongPressDetectorCount(0),
+  mPanDetectorCount(0),
+  mPinchDetectorCount(0),
+  mTapDetectorCount(0),
+  envOptionMinimumPanDistance(-1),
+  envOptionMinimumPanEvents(-1)
 {
 }
 
@@ -52,62 +55,59 @@ GestureEventProcessor::~GestureEventProcessor()
 {
 }
 
-void GestureEventProcessor::ProcessGestureEvent( Scene& scene, const Integration::GestureEvent& event)
+void GestureEventProcessor::ProcessTouchEvent( Scene& scene, const Integration::TouchEvent& event)
 {
-  if( Gesture::Started == event.state || Gesture::Continuing == event.state )
+  if( mLongPressDetectorCount > 0 )
   {
-    SetUpdateRequired();
+    mLongPressGestureProcessor.ProcessTouch(scene, event);
   }
-
-  switch(event.gestureType)
+  if( mPanDetectorCount > 0 )
   {
-    case Gesture::LongPress:
-      mLongPressGestureProcessor.Process( scene, static_cast<const Integration::LongPressGestureEvent&>(event) );
-      break;
-
-    case Gesture::Pan:
-      mPanGestureProcessor.Process( scene, static_cast<const Integration::PanGestureEvent&>(event));
-      break;
-
-    case Gesture::Pinch:
-      mPinchGestureProcessor.Process( scene, static_cast<const Integration::PinchGestureEvent&>(event));
-      break;
-
-    case Gesture::Tap:
-      mTapGestureProcessor.Process( scene, static_cast<const Integration::TapGestureEvent&>(event));
-      break;
+    mPanGestureProcessor.ProcessTouch(scene, event);
+  }
+  if( mPinchDetectorCount > 0 )
+  {
+    mPinchGestureProcessor.ProcessTouch(scene, event);
+  }
+  if( mTapDetectorCount > 0 )
+  {
+    mTapGestureProcessor.ProcessTouch(scene, event);
   }
 }
 
-void GestureEventProcessor::AddGestureDetector(GestureDetector* gestureDetector)
+void GestureEventProcessor::AddGestureDetector(GestureDetector* gestureDetector, Scene& scene)
 {
   switch (gestureDetector->GetType())
   {
     case Gesture::LongPress:
     {
       LongPressGestureDetector* longPress = static_cast<LongPressGestureDetector*>(gestureDetector);
-      mLongPressGestureProcessor.AddGestureDetector(longPress);
+      mLongPressGestureProcessor.AddGestureDetector(longPress, scene);
+      mLongPressDetectorCount++;
       break;
     }
 
     case Gesture::Pan:
     {
       PanGestureDetector* pan = static_cast<PanGestureDetector*>(gestureDetector);
-      mPanGestureProcessor.AddGestureDetector(pan);
+      mPanGestureProcessor.AddGestureDetector(pan, scene, envOptionMinimumPanDistance, envOptionMinimumPanEvents);
+      mPanDetectorCount++;
       break;
     }
 
     case Gesture::Pinch:
     {
       PinchGestureDetector* pinch = static_cast<PinchGestureDetector*>(gestureDetector);
-      mPinchGestureProcessor.AddGestureDetector(pinch);
+      mPinchGestureProcessor.AddGestureDetector(pinch, scene);
+      mPinchDetectorCount++;
       break;
     }
 
     case Gesture::Tap:
     {
       TapGestureDetector* tap = static_cast<TapGestureDetector*>(gestureDetector);
-      mTapGestureProcessor.AddGestureDetector(tap);
+      mTapGestureProcessor.AddGestureDetector(tap, scene);
+      mTapDetectorCount++;
       break;
     }
   }
@@ -121,6 +121,7 @@ void GestureEventProcessor::RemoveGestureDetector(GestureDetector* gestureDetect
     {
       LongPressGestureDetector* longPress = static_cast<LongPressGestureDetector*>(gestureDetector);
       mLongPressGestureProcessor.RemoveGestureDetector(longPress);
+      mLongPressDetectorCount--;
       break;
     }
 
@@ -128,6 +129,7 @@ void GestureEventProcessor::RemoveGestureDetector(GestureDetector* gestureDetect
     {
       PanGestureDetector* pan = static_cast<PanGestureDetector*>(gestureDetector);
       mPanGestureProcessor.RemoveGestureDetector(pan);
+      mPanDetectorCount--;
       break;
     }
 
@@ -135,6 +137,7 @@ void GestureEventProcessor::RemoveGestureDetector(GestureDetector* gestureDetect
     {
       PinchGestureDetector* pinch = static_cast<PinchGestureDetector*>(gestureDetector);
       mPinchGestureProcessor.RemoveGestureDetector(pinch);
+      mPinchDetectorCount--;
       break;
     }
 
@@ -142,6 +145,7 @@ void GestureEventProcessor::RemoveGestureDetector(GestureDetector* gestureDetect
     {
       TapGestureDetector* tap = static_cast<TapGestureDetector*>(gestureDetector);
       mTapGestureProcessor.RemoveGestureDetector(tap);
+      mTapDetectorCount--;
       break;
     }
   }
@@ -181,27 +185,16 @@ void GestureEventProcessor::GestureDetectorUpdated(GestureDetector* gestureDetec
   }
 }
 
-void GestureEventProcessor::SetUpdateRequired()
-{
-  mUpdateRequired = true;
-}
-
 void GestureEventProcessor::SetGestureProperties( const Gesture& gesture )
 {
-  if( Gesture::Started == gesture.state || Gesture::Continuing == gesture.state )
-  {
-    SetUpdateRequired();
-
-    // We may not be updating so we need to ask the render controller for an update.
-    mRenderController.RequestUpdate( false );
-  }
+  bool requestUpdate = false;
 
   switch ( gesture.type )
   {
     case Gesture::Pan:
     {
       const PanGesture& pan = static_cast< const PanGesture& >( gesture );
-      mPanGestureProcessor.SetPanGestureProperties( pan );
+      requestUpdate = mPanGestureProcessor.SetPanGestureProperties( pan );
       break;
     }
 
@@ -213,13 +206,22 @@ void GestureEventProcessor::SetGestureProperties( const Gesture& gesture )
       break;
     }
   }
+
+  if( requestUpdate )
+  {
+    // We may not be updating so we need to ask the render controller for an update.
+    mRenderController.RequestUpdate( false );
+  }
 }
 
 bool GestureEventProcessor::NeedsUpdate()
 {
-  bool updateRequired( mUpdateRequired );
+  bool updateRequired = false;
 
-  mUpdateRequired = false;
+  updateRequired |= mLongPressGestureProcessor.NeedsUpdate();
+  updateRequired |= mPanGestureProcessor.NeedsUpdate();
+  updateRequired |= mPinchGestureProcessor.NeedsUpdate();
+  updateRequired |= mTapGestureProcessor.NeedsUpdate();
 
   return updateRequired;
 }
@@ -304,6 +306,21 @@ void GestureEventProcessor::SetPanGestureMultitapSmoothingRange( int32_t value )
   mPanGestureProcessor.SetMultitapSmoothingRange( value );
 }
 
+void GestureEventProcessor::SetPanGestureMinimumDistance( int32_t value )
+{
+  envOptionMinimumPanDistance =  value;
+}
+
+void GestureEventProcessor::SetPanGestureMinimumPanEvents( int32_t value )
+{
+  envOptionMinimumPanEvents = value;
+}
+
+void GestureEventProcessor::SetPinchGestureMinimumDistance( float value)
+{
+  mPinchGestureProcessor.SetMinimumPinchDistance( value );
+}
+
 const PanGestureProcessor& GestureEventProcessor::GetPanGestureProcessor()
 {
   return mPanGestureProcessor;
index 903f5a6..6f6f42e 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_GESTURE_EVENT_PROCESSOR_H__
-#define __DALI_INTERNAL_GESTURE_EVENT_PROCESSOR_H__
+#ifndef DALI_INTERNAL_GESTURE_EVENT_PROCESSOR_H
+#define DALI_INTERNAL_GESTURE_EVENT_PROCESSOR_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,8 +33,7 @@ struct Gesture;
 
 namespace Integration
 {
-struct GestureEvent;
-class GestureManager;
+
 class RenderController;
 }
 
@@ -65,7 +64,7 @@ public:
    * @param[in] gestureManager The gesture manager
    * @param[in] renderController The render controller
    */
-  GestureEventProcessor( SceneGraph::UpdateManager& updateManager, Integration::GestureManager& gestureManager, Integration::RenderController& renderController );
+  GestureEventProcessor( SceneGraph::UpdateManager& updateManager, Integration::RenderController& renderController );
 
   /**
    * Non-virtual destructor; GestureProcessor is not a base class
@@ -75,10 +74,11 @@ public:
 public: // To be called by EventProcessor
 
   /**
-   * This function is called by Core whenever a gesture event occurs.
-   * @param[in] event The event that has occurred.
+   * This function is called by Core whenever a touch event occurs
+   * @param[in] scene The scene
+   * @param[in] event The event that has occurred
    */
-  void ProcessGestureEvent( Scene& scene, const Integration::GestureEvent& event );
+  void ProcessTouchEvent( Scene& scene, const Integration::TouchEvent& event);
 
 public: // To be called by gesture detectors
 
@@ -86,7 +86,7 @@ public: // To be called by gesture detectors
    * This method adds the specified gesture detector to the relevant gesture processor.
    * @param[in]  gestureDetector  The gesture detector to add
    */
-  void AddGestureDetector(GestureDetector* gestureDetector);
+  void AddGestureDetector(GestureDetector* gestureDetector, Scene& scene);
 
   /**
    * This method removes the specified gesture detector from the relevant gesture processor.
@@ -101,12 +101,6 @@ public: // To be called by gesture detectors
   void GestureDetectorUpdated(GestureDetector* gestureDetector);
 
   /**
-   * This method is called by GestureDetectors on Started or Continue state events.
-   * Status is queried and reset by Core in ProcessEvents
-   */
-  void SetUpdateRequired();
-
-  /**
    * Called by GestureDetectors to set the gesture properties in the update thread.
    * @param[in]  gesture  The gesture whose values will be used in the Update object.
    * @note If we are in the middle of processing the gesture being set, then this call is ignored.
@@ -237,6 +231,27 @@ public: // Called by Core
    */
   void SetPanGestureMultitapSmoothingRange( int32_t value );
 
+  /**
+   * @brief Sets the minimum distance required to start a pan event
+   *
+   * @param[in] value Distance in pixels
+   */
+  void SetPanGestureMinimumDistance( int32_t value );
+
+  /**
+   * @brief Sets the minimum number of touch events required to start a pan
+   *
+   * @param[in] value Number of touch events
+   */
+  void SetPanGestureMinimumPanEvents( int32_t value );
+
+  /**
+   * @brief Sets the minimum distance required to start a pinch event
+   *
+   * @param[in] value Distance in pixels
+   */
+  void SetPinchGestureMinimumDistance( float value);
+
 public: // needed for PanGesture
 
   /**
@@ -252,19 +267,23 @@ private:
 
 private:
 
-  Integration::GestureManager& mGestureManager;
-
   LongPressGestureProcessor mLongPressGestureProcessor;
   PanGestureProcessor mPanGestureProcessor;
   PinchGestureProcessor mPinchGestureProcessor;
   TapGestureProcessor mTapGestureProcessor;
   Integration::RenderController& mRenderController;
 
-  bool mUpdateRequired;     ///< set to true by gesture detectors if they require a Core::Update
+  uint32_t mLongPressDetectorCount;
+  uint32_t mPanDetectorCount;
+  uint32_t mPinchDetectorCount;
+  uint32_t mTapDetectorCount;
+
+  int32_t envOptionMinimumPanDistance;
+  int32_t envOptionMinimumPanEvents;
 };
 
 } // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_GESTURE_EVENT_PROCESSOR_H__
+#endif // DALI_INTERNAL_GESTURE_EVENT_PROCESSOR_H
similarity index 79%
rename from dali/integration-api/events/gesture-event.cpp
rename to dali/internal/event/events/gesture-event.cpp
index e3c2c50..3466004 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // CLASS HEADER
-#include <dali/integration-api/events/gesture-event.h>
+#include <dali/internal/event/events/gesture-event.h>
 
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 GestureEvent::~GestureEvent()
@@ -29,13 +29,12 @@ GestureEvent::~GestureEvent()
 }
 
 GestureEvent::GestureEvent(Gesture::Type gesture, Gesture::State gestureState)
-: Event(Gesture),
-  gestureType(gesture),
+: gestureType(gesture),
   state(gestureState),
   time(0)
 {
 }
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
similarity index 82%
rename from dali/integration-api/events/gesture-event.h
rename to dali/internal/event/events/gesture-event.h
index c3b0f04..8d3e0a3 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_GESTURE_EVENT_H__
-#define __DALI_INTEGRATION_GESTURE_EVENT_H__
+#ifndef DALI_INTERNAL_EVENT_GESTURE_EVENT_H
+#define DALI_INTERNAL_EVENT_GESTURE_EVENT_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 /**
  * This is the abstract base structure for any gestures that the adaptor detects and wishes to send
  * to the Core.
  */
-struct DALI_CORE_API GestureEvent : public Event
+struct GestureEvent
 {
   // Destruction
 
@@ -56,7 +56,7 @@ struct DALI_CORE_API GestureEvent : public Event
   /**
    * The time the gesture took place.
    */
-  unsigned int time;
+  uint32_t time;
 
 protected:  // Constructors only to be used by derived structures.
 
@@ -68,8 +68,8 @@ protected:  // Constructors only to be used by derived structures.
   GestureEvent(Gesture::Type gesture, Gesture::State gestureState);
 };
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_GESTURE_EVENT_H__
+#endif // DALI_INTERNAL_EVENT_GESTURE_EVENT_H
index 153dafb..d517666 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -70,8 +70,10 @@ struct GestureHitTestCheck : public HitTestAlgorithm::HitTestInterface
 
 
 GestureProcessor::GestureProcessor( Gesture::Type type )
-: mType( type ),
-  mCurrentGesturedActor( NULL ),
+: mGestureRecognizer(),
+  mNeedsUpdate( false ),
+  mType( type ),
+  mCurrentGesturedActor( nullptr ),
   mGesturedActorDisconnected( false )
 {
 }
@@ -81,6 +83,11 @@ GestureProcessor::~GestureProcessor()
   ResetActor();
 }
 
+void GestureProcessor::ProcessTouch( Scene& scene, const Integration::TouchEvent& event )
+{
+  mGestureRecognizer->SendEvent(scene, event);
+}
+
 void GestureProcessor::GetGesturedActor( Actor*& actor, GestureDetectorContainer& gestureDetectors )
 {
   while ( actor )
@@ -195,14 +202,14 @@ void GestureProcessor::ResetActor()
   if ( mCurrentGesturedActor )
   {
     mCurrentGesturedActor->RemoveObserver( *this );
-    mCurrentGesturedActor = NULL;
+    mCurrentGesturedActor = nullptr;
     mGesturedActorDisconnected = false;
   }
 }
 
 Actor* GestureProcessor::GetCurrentGesturedActor()
 {
-  return mGesturedActorDisconnected ? NULL : mCurrentGesturedActor;
+  return mGesturedActorDisconnected ? nullptr : mCurrentGesturedActor;
 }
 
 void GestureProcessor::SceneObjectRemoved(Object& object)
@@ -225,7 +232,7 @@ void GestureProcessor::ObjectDestroyed(Object& object)
     // Inform deriving classes.
     OnGesturedActorStageDisconnection();
 
-    mCurrentGesturedActor = NULL;
+    mCurrentGesturedActor = nullptr;
   }
 }
 
index 6e7f59e..af39967 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_GESTURE_PROCESSOR_H__
-#define __DALI_INTERNAL_GESTURE_PROCESSOR_H__
+#ifndef DALI_INTERNAL_GESTURE_PROCESSOR_H
+#define DALI_INTERNAL_GESTURE_PROCESSOR_H
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali/internal/event/events/gesture-detector-impl.h>
 #include <dali/internal/event/events/hit-test-algorithm-impl.h>
+#include <dali/internal/event/events/gesture-recognizer.h>
 #include <dali/internal/event/common/object-impl.h>
 
 namespace Dali
@@ -36,6 +37,26 @@ namespace Internal
  */
 class GestureProcessor : public Object::Observer
 {
+public:
+
+  /**
+   * Process the touch event in the attached recognizer
+   * @param[in] scene Scene.
+   * @param[in] event Touch event to process
+   */
+  void ProcessTouch( Scene& scene, const Integration::TouchEvent& event );
+
+  /**
+   * Returns whether any GestureDetector requires a Core::Update
+   * @return true if update required
+   */
+  inline bool NeedsUpdate()
+  {
+    bool updateRequired = mNeedsUpdate;
+    mNeedsUpdate = false;
+    return updateRequired;
+  }
+
 protected:
 
   // Construction & Destruction
@@ -161,6 +182,12 @@ private:
    */
   virtual void ObjectDestroyed(Object& object);
 
+
+protected:  //Data
+
+  GestureRecognizerPtr mGestureRecognizer;  ///< The gesture recognizer
+  bool   mNeedsUpdate;                 ///< Indicates if any GestureDetector requires a Core::Update
+
 private: // Data
 
   Gesture::Type mType;                 ///< Type of GestureProcessor
@@ -172,4 +199,4 @@ private: // Data
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_GESTURE_PROCESSOR_H__
+#endif // DALI_INTERNAL_GESTURE_PROCESSOR_H
diff --git a/dali/internal/event/events/gesture-recognizer.h b/dali/internal/event/events/gesture-recognizer.h
new file mode 100644 (file)
index 0000000..6efb254
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef DALI_INTERNAL_GESTURE_RECOGNIZER_H
+#define DALI_INTERNAL_GESTURE_RECOGNIZER_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/events/gesture.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/internal/event/events/gesture-event.h>
+
+namespace Dali
+{
+
+namespace Integration
+{
+struct TouchEvent;
+}
+
+namespace Internal
+{
+class GestureRequest;
+class Scene;
+
+template< typename T>
+class RecognizerObserver
+{
+public:
+  virtual void Process( Scene& scene, const T& event ) = 0;
+
+  virtual ~RecognizerObserver(){};
+};
+
+
+/**
+ * Abstract Base class for all adaptor gesture detectors.
+ *
+ * @note this may be replaced by gesture events sent directly from X.
+ */
+class GestureRecognizer : public RefObject
+{
+public:
+  /**
+   * Called when it gets a touch event.  The gesture recognizer should
+   * evaluate this event along with previously received events to determine
+   * whether the gesture they require has taken place.
+   * @param[in]  event  The latest touch event.
+   */
+  virtual void SendEvent(const Integration::TouchEvent& event) = 0;
+
+  /**
+   * Called when Core updates the gesture's detection requirements.
+   * @param[in]  request  The updated detection requirements.
+   */
+  virtual void Update(const GestureRequest& request) = 0;
+
+  /**
+   * Returns the type of gesture detector.
+   * @return Type of gesture detector.
+   */
+  Gesture::Type GetType() const { return mType; }
+
+  void SendEvent(Scene& scene, const Integration::TouchEvent& event)
+  {
+    mScene = &scene;
+    SendEvent(event);
+  }
+
+protected:
+
+  /**
+   * Protected Constructor.  Should only be able to create derived class objects.
+   * @param[in]  screenSize    The size of the screen.
+   * @param[in]  detectorType  The type of gesture detector.
+   */
+  GestureRecognizer( Vector2 screenSize, Gesture::Type detectorType )
+  : mScreenSize(screenSize),
+    mType(detectorType),
+    mScene(nullptr)
+  {
+  }
+
+  /**
+   * Virtual destructor.
+   */
+  virtual ~GestureRecognizer() {}
+
+protected:
+  Vector2 mScreenSize;
+  Gesture::Type mType;
+  Scene* mScene;
+};
+
+typedef IntrusivePtr<GestureRecognizer> GestureRecognizerPtr;
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_GESTURE_RECOGNIZER_H
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_GESTURE_REQUESTS_H__
-#define __DALI_INTEGRATION_GESTURE_REQUESTS_H__
+#ifndef DALI_INTERNAL_GESTURE_REQUESTS_H
+#define DALI_INTERNAL_GESTURE_REQUESTS_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 /**
  * This structure specifies the gesture type required (or no longer required) by Core.
  */
-struct DALI_CORE_API GestureRequest
+struct GestureRequest
 {
   // Creation & Destruction
 
@@ -57,7 +57,7 @@ struct DALI_CORE_API GestureRequest
 /**
  * This is used by Core when a pan gesture is required.
  */
-struct DALI_CORE_API PanGestureRequest : public GestureRequest
+struct PanGestureRequest : public GestureRequest
 {
   // Creation & Destruction
 
@@ -87,7 +87,7 @@ struct DALI_CORE_API PanGestureRequest : public GestureRequest
 /**
  * This is used by Core when a pinch gesture is required.
  */
-struct DALI_CORE_API PinchGestureRequest : public GestureRequest
+struct PinchGestureRequest : public GestureRequest
 {
   // Creation & Destruction
 
@@ -110,7 +110,7 @@ struct DALI_CORE_API PinchGestureRequest : public GestureRequest
 /**
  * This is used by Core when a tap gesture is required.
  */
-struct DALI_CORE_API TapGestureRequest : public GestureRequest
+struct TapGestureRequest : public GestureRequest
 {
   // Creation & Destruction
 
@@ -144,7 +144,7 @@ struct DALI_CORE_API TapGestureRequest : public GestureRequest
 /**
  * This is used by Core when a long press gesture is required.
  */
-struct DALI_CORE_API LongPressGestureRequest : public GestureRequest
+struct LongPressGestureRequest : public GestureRequest
 {
   // Creation & Destruction
 
@@ -171,8 +171,8 @@ struct DALI_CORE_API LongPressGestureRequest : public GestureRequest
   unsigned int maxTouches; ///< The maximum number of touch points required for a long press gesture.
 };
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_GESTURE_REQUESTS_H__
+#endif // DALI_INTERNAL_GESTURE_REQUESTS_H
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // CLASS HEADER
-#include "long-press-gesture-event.h"
+#include <dali/internal/event/events/long-press-gesture-event.h>
 
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 LongPressGestureEvent::LongPressGestureEvent( Gesture::State state )
@@ -34,6 +34,6 @@ LongPressGestureEvent::~LongPressGestureEvent()
 {
 }
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_LONG_PRESS_GESTURE_H__
-#define __DALI_INTEGRATION_LONG_PRESS_GESTURE_H__
+#ifndef DALI_INTERNAL_EVENT_LONG_PRESS_GESTURE_H
+#define DALI_INTERNAL_EVENT_LONG_PRESS_GESTURE_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // INTERNAL INCLUDES
-#include <dali/integration-api/events/gesture-event.h>
+#include <dali/internal/event/events/gesture-event.h>
 #include <dali/public-api/math/vector2.h>
 
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 /**
@@ -38,7 +38,7 @@ namespace Integration
  * - Finished:  When the user finally lifts all touches.
  * - Cancelled: If, after a down event, no long press is detected, or a system interruption.
  */
-struct DALI_CORE_API LongPressGestureEvent : public GestureEvent
+struct LongPressGestureEvent : public GestureEvent
 {
   // Construction & Destruction
 
@@ -68,8 +68,8 @@ struct DALI_CORE_API LongPressGestureEvent : public GestureEvent
   Vector2 point;
 };
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_LONG_PRESS_GESTURE_H__
+#endif // DALI_INTERNAL_EVENT_LONG_PRESS_GESTURE_H
index e8e613b..853e748 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
  */
 
 // CLASS HEADER
-#include "long-press-gesture-processor.h"
+#include <dali/internal/event/events/long-press-gesture-processor.h>
 
 // EXTERNAL INCLUDES
 #include <algorithm>
 #include <dali/public-api/actors/actor.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/events/long-press-gesture.h>
-#include <dali/integration-api/events/long-press-gesture-event.h>
-#include <dali/integration-api/gesture-manager.h>
+#include <dali/internal/event/events/long-press-gesture-event.h>
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/actors/actor-impl.h>
 #include <dali/internal/event/common/scene-impl.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
+#include <dali/internal/event/events/long-press-gesture-recognizer.h>
+#include <dali/internal/event/events/gesture-requests.h>
 
 namespace Dali
 {
@@ -51,7 +52,7 @@ namespace
 void EmitLongPressSignal(
     Actor* actor,
     const GestureDetectorContainer& gestureDetectors,
-    const Integration::LongPressGestureEvent& longPressEvent,
+    const LongPressGestureEvent& longPressEvent,
     Vector2 localPoint)
 {
   LongPressGesture longPress(longPressEvent.state);
@@ -98,10 +99,9 @@ struct IsNotAttachedFunctor
 
 } // unnamed namespace
 
-LongPressGestureProcessor::LongPressGestureProcessor( Integration::GestureManager& gestureManager)
+LongPressGestureProcessor::LongPressGestureProcessor()
 : GestureProcessor( Gesture::LongPress ),
-  mGestureManager( gestureManager ),
-  mGestureDetectors(),
+  mLongPressGestureDetectors(),
   mCurrentEmitters(),
   mCurrentRenderTask(),
   mMinTouchesRequired( 1 ),
@@ -114,7 +114,7 @@ LongPressGestureProcessor::~LongPressGestureProcessor()
 {
 }
 
-void LongPressGestureProcessor::Process( Scene& scene, const Integration::LongPressGestureEvent& longPressEvent )
+void LongPressGestureProcessor::Process( Scene& scene, const LongPressGestureEvent& longPressEvent )
 {
   switch ( longPressEvent.state )
   {
@@ -204,6 +204,7 @@ void LongPressGestureProcessor::Process( Scene& scene, const Integration::LongPr
       DALI_ABORT( "Incorrect state received from Integration layer: Continuing\n" );
       break;
     }
+
     case Gesture::Clear:
     {
       DALI_ABORT( "Incorrect state received from Integration layer: Clear\n" );
@@ -212,21 +213,24 @@ void LongPressGestureProcessor::Process( Scene& scene, const Integration::LongPr
   }
 }
 
-void LongPressGestureProcessor::AddGestureDetector( LongPressGestureDetector* gestureDetector )
+void LongPressGestureProcessor::AddGestureDetector( LongPressGestureDetector* gestureDetector, Scene& scene )
 {
-  bool firstRegistration(mGestureDetectors.empty());
+  bool firstRegistration(mLongPressGestureDetectors.empty());
 
-  mGestureDetectors.push_back(gestureDetector);
+  mLongPressGestureDetectors.push_back(gestureDetector);
 
   if (firstRegistration)
   {
     mMinTouchesRequired = gestureDetector->GetMinimumTouchesRequired();
     mMaxTouchesRequired = gestureDetector->GetMaximumTouchesRequired();
 
-    Integration::LongPressGestureRequest request;
+    LongPressGestureRequest request;
     request.minTouches = mMinTouchesRequired;
     request.maxTouches = mMaxTouchesRequired;
-    mGestureManager.Register( request );
+
+    Size size = scene.GetSize();
+
+    mGestureRecognizer = new LongPressGestureRecognizer(*this, Vector2(size.width, size.height), static_cast<const LongPressGestureRequest&>(request));
   }
   else
   {
@@ -237,16 +241,15 @@ void LongPressGestureProcessor::AddGestureDetector( LongPressGestureDetector* ge
 void LongPressGestureProcessor::RemoveGestureDetector( LongPressGestureDetector* gestureDetector )
 {
   // Find detector ...
-  LongPressGestureDetectorContainer::iterator endIter = std::remove( mGestureDetectors.begin(), mGestureDetectors.end(), gestureDetector );
-  DALI_ASSERT_DEBUG( endIter != mGestureDetectors.end() );
+  LongPressGestureDetectorContainer::iterator endIter = std::remove( mLongPressGestureDetectors.begin(), mLongPressGestureDetectors.end(), gestureDetector );
+  DALI_ASSERT_DEBUG( endIter != mLongPressGestureDetectors.end() );
 
   // ... and remove it
-  mGestureDetectors.erase( endIter, mGestureDetectors.end() );
+  mLongPressGestureDetectors.erase( endIter, mLongPressGestureDetectors.end() );
 
-  if ( mGestureDetectors.empty() )
+  if ( mLongPressGestureDetectors.empty() )
   {
-    Integration::GestureRequest request( Gesture::LongPress );
-    mGestureManager.Unregister(request);
+    mGestureRecognizer.Detach();
   }
   else
   {
@@ -256,19 +259,19 @@ void LongPressGestureProcessor::RemoveGestureDetector( LongPressGestureDetector*
 
 void LongPressGestureProcessor::GestureDetectorUpdated( LongPressGestureDetector* gestureDetector )
 {
-  DALI_ASSERT_DEBUG( find( mGestureDetectors.begin(), mGestureDetectors.end(), gestureDetector ) != mGestureDetectors.end() );
+  DALI_ASSERT_DEBUG( find( mLongPressGestureDetectors.begin(), mLongPressGestureDetectors.end(), gestureDetector ) != mLongPressGestureDetectors.end() );
 
   UpdateDetection();
 }
 
 void LongPressGestureProcessor::UpdateDetection()
 {
-  DALI_ASSERT_DEBUG(!mGestureDetectors.empty());
+  DALI_ASSERT_DEBUG(!mLongPressGestureDetectors.empty());
 
   unsigned int minimumRequired = UINT_MAX;
   unsigned int maximumRequired = 0;
 
-  for ( LongPressGestureDetectorContainer::iterator iter = mGestureDetectors.begin(), endIter = mGestureDetectors.end(); iter != endIter; ++iter )
+  for ( LongPressGestureDetectorContainer::iterator iter = mLongPressGestureDetectors.begin(), endIter = mLongPressGestureDetectors.end(); iter != endIter; ++iter )
   {
     LongPressGestureDetector* current(*iter);
 
@@ -293,10 +296,10 @@ void LongPressGestureProcessor::UpdateDetection()
     mMinTouchesRequired = minimumRequired;
     mMaxTouchesRequired = maximumRequired;
 
-    Integration::LongPressGestureRequest request;
+    LongPressGestureRequest request;
     request.minTouches = mMinTouchesRequired;
     request.maxTouches = mMaxTouchesRequired;
-    mGestureManager.Update(request);
+    mGestureRecognizer->Update(request);
   }
 }
 
index d35c0a7..f711686 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_LONG_PRESS_GESTURE_EVENT_PROCESSOR_H__
-#define __DALI_INTERNAL_LONG_PRESS_GESTURE_EVENT_PROCESSOR_H__
+#ifndef DALI_INTERNAL_LONG_PRESS_GESTURE_EVENT_PROCESSOR_H
+#define DALI_INTERNAL_LONG_PRESS_GESTURE_EVENT_PROCESSOR_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 namespace Dali
 {
 
-namespace Integration
-{
-class GestureManager;
-struct GestureEvent;
-struct LongPressGestureEvent;
-}
-
 namespace Internal
 {
 
 class Stage;
 class Scene;
 
+struct GestureEvent;
+struct LongPressGestureEvent;
+
 /**
  * Long Press Gesture Event Processing:
  *
@@ -46,15 +42,14 @@ class Scene;
  * - Find the actor that requires a long-press at the long press position.
  * - Emit the gesture if the event satisfies the detector conditions.
  */
-class LongPressGestureProcessor : public GestureProcessor
+class LongPressGestureProcessor : public GestureProcessor, public RecognizerObserver<LongPressGestureEvent>
 {
 public:
 
   /**
    * Create a long press gesture processor.
-   * @param[in] gestureManager The gesture manager.
    */
-  LongPressGestureProcessor( Integration::GestureManager& gestureManager );
+  LongPressGestureProcessor();
 
   /**
    * Non-virtual destructor; LongPressGestureProcessor is not a base class
@@ -68,15 +63,16 @@ public: // To be called by GestureEventProcessor
    * @param[in] scene The scene the long press gesture event occurs in.
    * @param[in] longPressEvent The event that has occurred.
    */
-  void Process( Scene& scene, const Integration::LongPressGestureEvent& longPressEvent );
+  void Process( Scene& scene, const LongPressGestureEvent& longPressEvent );
 
   /**
    * Adds a gesture detector to this gesture processor.
    * If this is the first gesture detector being added, then this method registers the required
    * gesture with the adaptor.
    * @param[in]  gestureDetector  The gesture detector being added.
+   * @param[in] scene The scene the long press gesture event occurs in.
    */
-  void AddGestureDetector( LongPressGestureDetector* gestureDetector );
+  void AddGestureDetector( LongPressGestureDetector* gestureDetector, Scene& scene );
 
   /**
    * Removes the specified gesture detector from this gesture processor.  If, after removing this
@@ -125,8 +121,7 @@ private:
 
 private:
 
-  Integration::GestureManager& mGestureManager;
-  LongPressGestureDetectorContainer mGestureDetectors;
+  LongPressGestureDetectorContainer mLongPressGestureDetectors;
 
   GestureDetectorContainer mCurrentEmitters;
   RenderTaskPtr mCurrentRenderTask;
@@ -134,11 +129,11 @@ private:
   uint32_t mMinTouchesRequired;
   uint32_t mMaxTouchesRequired;
 
-  const Integration::LongPressGestureEvent* mCurrentLongPressEvent; ///< Pointer to current longPressEvent, used when calling ProcessAndEmit()
+  const LongPressGestureEvent* mCurrentLongPressEvent; ///< Pointer to current longPressEvent, used when calling ProcessAndEmit()
 };
 
 } // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_LONG_PRESS_GESTURE_EVENT_PROCESSOR_H__
+#endif // DALI_INTERNAL_LONG_PRESS_GESTURE_EVENT_PROCESSOR_H
diff --git a/dali/internal/event/events/long-press-gesture-recognizer.cpp b/dali/internal/event/events/long-press-gesture-recognizer.cpp
new file mode 100644 (file)
index 0000000..c15f8d3
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/event/events/long-press-gesture-recognizer.h>
+
+// EXTERNAL INCLUDES
+#include <cmath>
+
+#include <dali/public-api/events/touch-point.h>
+#include <dali/public-api/math/vector2.h>
+
+#include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/internal/event/events/gesture-requests.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/platform-abstraction.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace
+{
+// TODO: Set these according to DPI
+const float MAXIMUM_MOTION_ALLOWED = 60.0f;
+// TODO: Set this time according to system setting (vconf)
+const unsigned long LONG_PRESS_TIME = 500u;
+} // unnamed namespace
+
+LongPressGestureRecognizer::LongPressGestureRecognizer(Observer& observer, Vector2 screenSize, const LongPressGestureRequest& request )
+: GestureRecognizer( screenSize, Gesture::LongPress ),
+  mObserver( observer ),
+  mState( Clear ),
+  mMinimumTouchesRequired( request.minTouches ),
+  mMaximumTouchesRequired( request.maxTouches ),
+  mTouchTime( 0 ),
+  mTimerId( 0 )
+{
+}
+
+LongPressGestureRecognizer::~LongPressGestureRecognizer()
+{
+}
+
+void LongPressGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
+{
+  unsigned int pointCount( event.GetPointCount() );
+  Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
+
+  switch (mState)
+  {
+    // Clear: Wait till one point touches the screen before starting timer.
+    case Clear:
+    {
+      const Integration::Point& point = event.points[0];
+
+      if ( point.GetState() == PointState::DOWN )
+      {
+        mTouchPositions.clear();
+        mTouchPositions[point.GetDeviceId()] = point.GetScreenPosition();
+
+        mTouchTime = event.time;
+
+        mTimerId = platformAbstraction.StartTimer(GetSystemValue(), MakeCallback( this, &LongPressGestureRecognizer::TimerCallback));
+
+        // A long press gesture may be possible, tell Core about this and change state to Touched.
+        mState = Touched;
+        EmitGesture( Gesture::Possible );
+      }
+
+      break;
+    }
+
+    // Touched: Monitor movement and addition/removal of points.
+    case Touched:
+    {
+      if (pointCount > mMaximumTouchesRequired)
+      {
+        // A long press did not occur, tell Core that it was cancelled and change state to Failed.
+        EmitGesture( Gesture::Cancelled );
+        mTouchPositions.clear();
+        platformAbstraction.CancelTimer(mTimerId);
+        mState = Failed;
+        break;
+      }
+
+      bool endLoop(false);
+
+      for ( Integration::PointContainerConstIterator iter = event.points.begin(), endIter = event.points.end();
+           iter != endIter && !endLoop; ++iter)
+      {
+        switch( iter->GetState() )
+        {
+          // add point.
+          case PointState::DOWN:
+          {
+            mTouchPositions[iter->GetDeviceId()] = iter->GetScreenPosition();
+            break;
+          }
+
+          // remove point.
+          case PointState::UP:
+          case PointState::INTERRUPTED:
+          {
+            // System has interrupted us, long press is not possible, inform Core
+            EmitGesture( Gesture::Cancelled );
+            mTouchPositions.clear();
+            platformAbstraction.CancelTimer(mTimerId);
+            mState = ( pointCount == 1 ) ? Clear : Failed; // Change state to Clear if only one point, Failed otherwise.
+            endLoop = true;
+            break;
+          }
+
+          case PointState::MOTION:
+          {
+            const Vector2 touchPosition( mTouchPositions[iter->GetDeviceId()] - iter->GetScreenPosition() );
+            float distanceSquared = touchPosition.LengthSquared();
+
+            if (distanceSquared > ( MAXIMUM_MOTION_ALLOWED * MAXIMUM_MOTION_ALLOWED ) )
+            {
+              // We have moved more than the allowable motion for a long press gesture. Inform Core and change state to Failed.
+              EmitGesture( Gesture::Cancelled );
+              platformAbstraction.CancelTimer(mTimerId);
+              mState = Failed;
+              endLoop = true;
+            }
+            break;
+          }
+
+          case PointState::STATIONARY:
+          case PointState::LEAVE:
+          {
+            break;
+          }
+        }
+      }
+      break;
+    }
+
+    // Failed/Finished: Monitor the touches, waiting for all touches to be released.
+    case Failed:
+    case Finished:
+    {
+      // eventually the final touch point will be removed, marking the end of this gesture.
+      if ( pointCount == 1 )
+      {
+        PointState::Type primaryPointState = event.points[0].GetState();
+
+        if ( (primaryPointState == PointState::UP) || (primaryPointState == PointState::INTERRUPTED) )
+        {
+          if(mState == Finished)
+          {
+            // When the last touch point is lifted, we should inform the Core that the Long press has finished.
+            EmitGesture(Gesture::Finished);
+          }
+          mTouchPositions.clear();
+          mState = Clear; // Reset state to clear when last touch point is lifted.
+        }
+      }
+      break;
+    }
+  }
+}
+
+void LongPressGestureRecognizer::Update(const GestureRequest& request)
+{
+  const LongPressGestureRequest& longPress = static_cast<const LongPressGestureRequest&>(request);
+
+  mMinimumTouchesRequired = longPress.minTouches;
+  mMaximumTouchesRequired = longPress.maxTouches;
+}
+
+bool LongPressGestureRecognizer::TimerCallback()
+{
+  EmitGesture(Gesture::Started);
+
+  mState = Finished;
+
+  return false;
+}
+
+void LongPressGestureRecognizer::EmitGesture(Gesture::State state)
+{
+  unsigned int touchPoints ( static_cast<unsigned int>( mTouchPositions.size() ) );
+
+  // We should tell Core about the Possible and Cancelled states regardless of whether we have satisfied long press requirements.
+  if ( (state == Gesture::Possible) ||
+       (state == Gesture::Cancelled) ||
+       (touchPoints >= mMinimumTouchesRequired) )
+  {
+    LongPressGestureEvent longPress( state );
+    longPress.numberOfTouches = touchPoints;
+
+    for (std::map<int, Vector2>::iterator iter = mTouchPositions.begin(), endIter = mTouchPositions.end();
+         iter != endIter; ++iter)
+    {
+      longPress.point += iter->second;
+    }
+    longPress.point /= static_cast<float>( touchPoints );
+
+    longPress.time = mTouchTime;
+    if ( state != Gesture::Possible )
+    {
+      longPress.time += GetSystemValue();
+    }
+
+    if( mScene )
+    {
+      // Create another handle so the recognizer cannot be destroyed during process function
+      GestureRecognizerPtr recognizerHandle = this;
+
+      mObserver.Process(*mScene, longPress);
+    }
+  }
+}
+
+int LongPressGestureRecognizer::GetSystemValue()
+{
+  return LONG_PRESS_TIME;
+}
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/dali/internal/event/events/long-press-gesture-recognizer.h b/dali/internal/event/events/long-press-gesture-recognizer.h
new file mode 100644 (file)
index 0000000..18f19e3
--- /dev/null
@@ -0,0 +1,130 @@
+#ifndef DALI_INTERNAL_LONG_PRESS_GESTURE_DETECTOR_H
+#define DALI_INTERNAL_LONG_PRESS_GESTURE_DETECTOR_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <map>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/events/gesture-recognizer.h>
+#include <dali/internal/event/events/long-press-gesture-event.h>
+
+namespace Dali
+{
+
+namespace Integration
+{
+struct TouchEvent;
+
+}
+
+namespace Internal
+{
+
+struct LongPressGestureRequest;
+class CoreEventInterface;
+
+/**
+ * When given a set of touch events, this detector attempts to determine if a long press gesture has taken place.
+ * Emits a LongPressGestureEvent (state = Started) when a long press has been detected (Touch held down for more than duration).
+ * Emits a further LongPressGestureEvent (state = Finished) when a long press has been completed (Touch Release).
+ */
+class LongPressGestureRecognizer : public GestureRecognizer
+{
+public:
+
+  using Observer = RecognizerObserver<LongPressGestureEvent>;
+
+  /**
+   * Constructor
+   * @param[in] coreEventInterface Used to send events to Core.
+   * @param[in] screenSize  The size of the screen.
+   * @param[in] request     The long press gesture request.
+   */
+  LongPressGestureRecognizer( Observer& observer, Vector2 screenSize, const LongPressGestureRequest& request );
+
+  /**
+   * Virtual destructor.
+   */
+  virtual ~LongPressGestureRecognizer();
+
+public:
+
+  /**
+   * @copydoc Dali::Internal::GestureDetector::SendEvent(const Integration::TouchEvent&)
+   */
+  virtual void SendEvent(const Integration::TouchEvent& event);
+
+  /**
+   * @copydoc Dali::Internal::GestureDetector::Update(const Integration::GestureRequest&)
+   */
+  virtual void Update(const GestureRequest& request);
+
+private:
+
+  /**
+   * Timer Callback
+   * @return will return false; one-shot timer.
+   */
+  bool TimerCallback();
+
+  /**
+   * Emits the long press gesture if all conditions are applicable.
+   * @param[in] state The state of this gesture event.
+   */
+  void EmitGesture(Gesture::State state);
+
+  /**
+   * Get current system setting value for tap and hold gesture
+   * @return system value for tap and hold gesture [ms]
+   */
+  int GetSystemValue();
+
+private:
+
+  // Reference to the gesture processor for this recognizer
+  Observer& mObserver;
+
+  /**
+   * Internal state machine.
+   */
+  enum State
+  {
+    Clear,      ///< No gesture detected.
+    Touched,    ///< User is touching the screen.
+    Failed,     ///< Gesture has failed.
+    Finished    ///< Gesture has been detected and sent.
+  };
+
+  State mState; ///< The current state of the detector.
+
+  unsigned int mMinimumTouchesRequired;   ///< The minimum touches required before emitting a long press.
+  unsigned int mMaximumTouchesRequired;   ///< The maximum touches allowable. Any more and a long press is not emitted.
+
+  std::map<int, Vector2> mTouchPositions; ///< A map with all the touch down positions.
+  uint32_t mTouchTime;               ///< The time we first pressed down.
+
+  uint32_t mTimerId;
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_LONG_PRESS_GESTURE_DETECTOR_H
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // CLASS HEADER
-#include <dali/integration-api/events/pan-gesture-event.h>
+#include <dali/internal/event/events/pan-gesture-event.h>
 
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 
@@ -36,6 +36,6 @@ PanGestureEvent::~PanGestureEvent()
 {
 }
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_PAN_GESTURE_EVENT_H__
-#define __DALI_INTEGRATION_PAN_GESTURE_EVENT_H__
+#ifndef DALI_INTERNAL_EVENT_PAN_GESTURE_EVENT_H
+#define DALI_INTERNAL_EVENT_PAN_GESTURE_EVENT_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // INTERNAL INCLUDES
-#include <dali/integration-api/events/gesture-event.h>
+#include <dali/internal/event/events/gesture-event.h>
 #include <dali/public-api/math/vector2.h>
 
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 /**
@@ -42,7 +42,7 @@ namespace Integration
  * A Started state will be ignored if a Possible state does not precede it.
  * Likewise, a Continuing or Finished state will be ignored if a Started state does not precede it.
  */
-struct DALI_CORE_API PanGestureEvent: public GestureEvent
+struct PanGestureEvent: public GestureEvent
 {
   // Construction & Destruction
 
@@ -80,8 +80,8 @@ struct DALI_CORE_API PanGestureEvent: public GestureEvent
   unsigned int numberOfTouches;
 };
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_PAN_GESTURE_EVENT_H__
+#endif // DALI_INTERNAL_EVENT_PAN_GESTURE_EVENT_H
index d413f03..5ade85c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 // CLASS HEADER
 #include <dali/internal/event/events/pan-gesture-processor.h>
 
+#if defined(DEBUG_ENABLED)
+#include <sstream>
+#endif
+
 // EXTERNAL INCLUDES
 #include <algorithm>
 
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/events/pan-gesture.h>
 #include <dali/public-api/math/vector2.h>
-#include <dali/integration-api/events/pan-gesture-event.h>
-#include <dali/integration-api/gesture-manager.h>
+#include <dali/internal/event/events/pan-gesture-event.h>
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/common/scene-impl.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
+#include <dali/internal/event/events/multi-point-event-util.h>
+#include <dali/internal/event/events/pan-gesture-recognizer.h>
+#include <dali/internal/event/events/gesture-requests.h>
 
 namespace Dali
 {
@@ -42,6 +48,21 @@ namespace Internal
 namespace // unnamed namespace
 {
 
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_PAN_PROCESSOR" );
+
+const char * GESTURE_STATES[ 6 ] =
+{
+  "Clear",
+  "Started",
+  "Continuing",
+  "Finished",
+  "Cancelled",
+  "Possible"
+};
+
+#endif // defined(DEBUG_ENABLED)
+
 const unsigned long MAXIMUM_TIME_WITH_VALID_LAST_VELOCITY( 50u );
 
 /**
@@ -101,16 +122,15 @@ struct IsNotAttachedAndOutsideTouchesRangeFunctor
 
 } // unnamed namespace
 
-PanGestureProcessor::PanGestureProcessor( Integration::GestureManager& gestureManager, SceneGraph::UpdateManager& updateManager )
+PanGestureProcessor::PanGestureProcessor( SceneGraph::UpdateManager& updateManager )
 : GestureProcessor( Gesture::Pan ),
-  mGestureManager( gestureManager ),
-  mGestureDetectors(),
+  mPanGestureDetectors(),
   mCurrentPanEmitters(),
   mCurrentRenderTask(),
   mPossiblePanPosition(),
   mMinTouchesRequired( 1 ),
   mMaxTouchesRequired( 1 ),
-  mCurrentPanEvent( NULL ),
+  mCurrentPanEvent( nullptr ),
   mSceneObject( SceneGraph::PanGesture::New() ) // Create scene object to store pan information.
 {
   // Pass ownership to scene-graph; scene object lives for the lifecycle of UpdateManager
@@ -119,11 +139,21 @@ PanGestureProcessor::PanGestureProcessor( Integration::GestureManager& gestureMa
 
 PanGestureProcessor::~PanGestureProcessor()
 {
-  mSceneObject = NULL; // mSceneObject is owned and destroyed by update manager (there is only one of these for now)
+  mSceneObject = nullptr; // mSceneObject is owned and destroyed by update manager (there is only one of these for now)
 }
 
-void PanGestureProcessor::Process( Scene& scene, const Integration::PanGestureEvent& panEvent )
+void PanGestureProcessor::Process( Scene& scene, const PanGestureEvent& panEvent )
 {
+#if defined(DEBUG_ENABLED)
+  DALI_LOG_TRACE_METHOD( gLogFilter );
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "    Pan Event\n");
+  DALI_LOG_INFO( gLogFilter, Debug::General, "      State: %s  Touches: %d  Time: %d  TimeDelta: %d\n",
+                                             GESTURE_STATES[panEvent.state], panEvent.numberOfTouches, panEvent.time, panEvent.timeDelta);
+  DALI_LOG_INFO( gLogFilter, Debug::General, "      Positions: Current: (%.0f, %.0f), Previous: (%.0f, %.0f)\n",
+                                             panEvent.currentPosition.x, panEvent.currentPosition.y, panEvent.previousPosition.x, panEvent.previousPosition.y);
+#endif
+
   switch( panEvent.state )
   {
     case Gesture::Possible:
@@ -143,6 +173,9 @@ void PanGestureProcessor::Process( Scene& scene, const Integration::PanGestureEv
 
     case Gesture::Started:
     {
+      // Requires a core update
+      mNeedsUpdate = true;
+
       if ( GetCurrentGesturedActor() )
       {
         // The pan gesture should only be sent to the gesture detector which first received it so that
@@ -159,7 +192,7 @@ void PanGestureProcessor::Process( Scene& scene, const Integration::PanGestureEv
           // Set mCurrentPanEvent to use inside overridden methods called in ProcessAndEmit()
           mCurrentPanEvent = &panEvent;
           ProcessAndEmit( hitTestResults );
-          mCurrentPanEvent = NULL;
+          mCurrentPanEvent = nullptr;
         }
         else
         {
@@ -171,6 +204,11 @@ void PanGestureProcessor::Process( Scene& scene, const Integration::PanGestureEv
     }
 
     case Gesture::Continuing:
+    {
+      // Requires a core update
+      mNeedsUpdate = true;
+    }
+    // No break, Fallthrough
     case Gesture::Finished:
     case Gesture::Cancelled:
     {
@@ -231,21 +269,23 @@ void PanGestureProcessor::Process( Scene& scene, const Integration::PanGestureEv
   }
 }
 
-void PanGestureProcessor::AddGestureDetector( PanGestureDetector* gestureDetector )
+void PanGestureProcessor::AddGestureDetector( PanGestureDetector* gestureDetector, Scene& scene, int32_t minDistance, int32_t minPanEvents )
 {
-  bool firstRegistration(mGestureDetectors.empty());
+  bool firstRegistration(mPanGestureDetectors.empty());
 
-  mGestureDetectors.push_back(gestureDetector);
+  mPanGestureDetectors.push_back(gestureDetector);
 
   if (firstRegistration)
   {
     mMinTouchesRequired = gestureDetector->GetMinimumTouchesRequired();
     mMaxTouchesRequired = gestureDetector->GetMaximumTouchesRequired();
 
-    Integration::PanGestureRequest request;
+    PanGestureRequest request;
     request.minTouches = mMinTouchesRequired;
     request.maxTouches = mMaxTouchesRequired;
-    mGestureManager.Register(request);
+
+    Size size = scene.GetSize();
+    mGestureRecognizer = new PanGestureRecognizer(*this, Vector2(size.width, size.height), static_cast<const PanGestureRequest&>(request), minDistance, minPanEvents);
   }
   else
   {
@@ -269,16 +309,15 @@ void PanGestureProcessor::RemoveGestureDetector( PanGestureDetector* gestureDete
   }
 
   // Find the detector...
-  PanGestureDetectorContainer::iterator endIter = std::remove( mGestureDetectors.begin(), mGestureDetectors.end(), gestureDetector );
-  DALI_ASSERT_DEBUG( endIter != mGestureDetectors.end() );
+  PanGestureDetectorContainer::iterator endIter = std::remove( mPanGestureDetectors.begin(), mPanGestureDetectors.end(), gestureDetector );
+  DALI_ASSERT_DEBUG( endIter != mPanGestureDetectors.end() );
 
   // ...and remove it
-  mGestureDetectors.erase(endIter, mGestureDetectors.end());
+  mPanGestureDetectors.erase(endIter, mPanGestureDetectors.end());
 
-  if (mGestureDetectors.empty())
+  if (mPanGestureDetectors.empty())
   {
-    Integration::GestureRequest request(Gesture::Pan);
-    mGestureManager.Unregister(request);
+    mGestureRecognizer.Detach();
   }
   else
   {
@@ -288,12 +327,12 @@ void PanGestureProcessor::RemoveGestureDetector( PanGestureDetector* gestureDete
 
 void PanGestureProcessor::GestureDetectorUpdated( PanGestureDetector* gestureDetector )
 {
-  DALI_ASSERT_DEBUG(find(mGestureDetectors.begin(), mGestureDetectors.end(), gestureDetector) != mGestureDetectors.end());
+  DALI_ASSERT_DEBUG(find(mPanGestureDetectors.begin(), mPanGestureDetectors.end(), gestureDetector) != mPanGestureDetectors.end());
 
   UpdateDetection();
 }
 
-void PanGestureProcessor::SetPanGestureProperties( const PanGesture& pan )
+bool PanGestureProcessor::SetPanGestureProperties( const PanGesture& pan )
 {
   // If we are currently processing a pan gesture then just ignore
   if ( mCurrentPanEmitters.empty() && mSceneObject )
@@ -301,7 +340,14 @@ void PanGestureProcessor::SetPanGestureProperties( const PanGesture& pan )
     // We update the scene object directly rather than sending a message.
     // Sending a message could cause unnecessary delays, the scene object ensure thread safe behaviour.
     mSceneObject->AddGesture( pan );
+
+    if( Gesture::Started == pan.state || Gesture::Continuing == pan.state )
+    {
+      mNeedsUpdate = true;
+    }
   }
+
+  return mNeedsUpdate;
 }
 
 void PanGestureProcessor::EnableProfiling()
@@ -403,12 +449,12 @@ const SceneGraph::PanGesture& PanGestureProcessor::GetSceneObject() const
 
 void PanGestureProcessor::UpdateDetection()
 {
-  DALI_ASSERT_DEBUG(!mGestureDetectors.empty());
+  DALI_ASSERT_DEBUG(!mPanGestureDetectors.empty());
 
   unsigned int minimumRequired = UINT_MAX;
   unsigned int maximumRequired = 0;
 
-  for ( PanGestureDetectorContainer::iterator iter = mGestureDetectors.begin(), endIter = mGestureDetectors.end(); iter != endIter; ++iter )
+  for ( PanGestureDetectorContainer::iterator iter = mPanGestureDetectors.begin(), endIter = mPanGestureDetectors.end(); iter != endIter; ++iter )
   {
     PanGestureDetector* detector(*iter);
 
@@ -433,16 +479,16 @@ void PanGestureProcessor::UpdateDetection()
     mMinTouchesRequired = minimumRequired;
     mMaxTouchesRequired = maximumRequired;
 
-    Integration::PanGestureRequest request;
+    PanGestureRequest request;
     request.minTouches = mMinTouchesRequired;
     request.maxTouches = mMaxTouchesRequired;
-    mGestureManager.Update(request);
+    mGestureRecognizer->Update(request);
   }
 }
 
 void PanGestureProcessor::EmitPanSignal( Actor* actor,
                                          const GestureDetectorContainer& gestureDetectors,
-                                         const Integration::PanGestureEvent& panEvent,
+                                         const PanGestureEvent& panEvent,
                                          Vector2 localCurrent,
                                          Gesture::State state,
                                          RenderTaskPtr renderTask )
@@ -503,6 +549,7 @@ void PanGestureProcessor::EmitPanSignal( Actor* actor,
     }
 
     Dali::Actor actorHandle( actor );
+
     const GestureDetectorContainer::const_iterator endIter = gestureDetectors.end();
     for ( GestureDetectorContainer::const_iterator iter = gestureDetectors.begin(); iter != endIter; ++iter )
     {
index bc0bdb3..dcc813c 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_PAN_GESTURE_EVENT_PROCESSOR_H__
-#define __DALI_INTERNAL_PAN_GESTURE_EVENT_PROCESSOR_H__
+#ifndef DALI_INTERNAL_EVENT_PAN_GESTURE_EVENT_PROCESSOR_H
+#define DALI_INTERNAL_EVENT_PAN_GESTURE_EVENT_PROCESSOR_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 namespace Dali
 {
 
-namespace Integration
-{
-class GestureManager;
-struct GestureEvent;
-struct PanGestureEvent;
-}
-
 namespace Internal
 {
 
 class Stage;
 class Scene;
+struct GestureEvent;
+struct PanGestureEvent;
 
 namespace SceneGraph
 {
@@ -55,7 +50,7 @@ class UpdateManager;
  * The above is only checked when our gesture starts.  We continue sending the pan gesture to the
  * same actor and detector until the pan ends or is cancelled.
  */
-class PanGestureProcessor : public GestureProcessor
+class PanGestureProcessor : public GestureProcessor, public RecognizerObserver<PanGestureEvent>
 {
 public:
 
@@ -64,7 +59,7 @@ public:
    * @param[in] gestureManager The gesture manager
    * @param[in] updateManager The Update Manager
    */
-  PanGestureProcessor( Integration::GestureManager& gestureManager, SceneGraph::UpdateManager& updateManager );
+  PanGestureProcessor( SceneGraph::UpdateManager& updateManager );
 
   /**
    * Destructor
@@ -78,7 +73,7 @@ public: // To be called by GestureEventProcessor
    * @param[in] scene The scene the pan gesture event occurs in.
    * @param[in] panEvent The event that has occurred.
    */
-  void Process( Scene& scene, const Integration::PanGestureEvent& panEvent );
+  void Process( Scene& scene, const PanGestureEvent& panEvent );
 
   /**
    * Adds a gesture detector to this gesture processor.
@@ -86,7 +81,7 @@ public: // To be called by GestureEventProcessor
    * gesture with the adaptor.
    * @param[in]  gestureDetector  The gesture detector being added.
    */
-  void AddGestureDetector( PanGestureDetector* gestureDetector );
+  void AddGestureDetector( PanGestureDetector* gestureDetector, Scene& scene, int32_t minDistance, int32_t minPanEvents );
 
   /**
    * Removes the specified gesture detector from this gesture processor.  If, after removing this
@@ -105,9 +100,10 @@ public: // To be called by GestureEventProcessor
   /**
    * Sets the pan gesture properties stored in the scene object directly,
    * @param[in]  pan  The pan gesture to override the properties with.
+   * @return true if Core::Update required
    * @note If we are already processing a normal pan, then this call is ignored.
    */
-  void SetPanGestureProperties( const PanGesture& pan );
+  bool SetPanGestureProperties( const PanGesture& pan );
 
   /**
    * Called to provide pan-gesture profiling information.
@@ -257,7 +253,7 @@ private:
    */
   void EmitPanSignal( Actor* actor,
                       const GestureDetectorContainer& gestureDetectors,
-                      const Integration::PanGestureEvent& panEvent,
+                      const PanGestureEvent& panEvent,
                       Vector2 localCurrent,
                       Gesture::State state,
                       RenderTaskPtr renderTask );
@@ -281,8 +277,7 @@ private:
 
 private:
 
-  Integration::GestureManager& mGestureManager;
-  PanGestureDetectorContainer mGestureDetectors;
+  PanGestureDetectorContainer mPanGestureDetectors;
   GestureDetectorContainer mCurrentPanEmitters;
   RenderTaskPtr mCurrentRenderTask;
   Vector2 mPossiblePanPosition;
@@ -293,7 +288,7 @@ private:
   Vector2 mLastVelocity;       ///< The last recorded velocity in local actor coordinates.
   Vector2 mLastScreenVelocity; ///< The last recorded velocity in screen coordinates.
 
-  const Integration::PanGestureEvent* mCurrentPanEvent; ///< Pointer to current PanEvent, used when calling ProcessAndEmit()
+  const PanGestureEvent* mCurrentPanEvent; ///< Pointer to current PanEvent, used when calling ProcessAndEmit()
   SceneGraph::PanGesture* mSceneObject; ///< Not owned, but we write to it directly
 };
 
@@ -301,4 +296,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_PAN_GESTURE_EVENT_PROCESSOR_H__
+#endif // DALI_INTERNAL_EVENT_PAN_GESTURE_EVENT_PROCESSOR_H
diff --git a/dali/internal/event/events/pan-gesture-recognizer.cpp b/dali/internal/event/events/pan-gesture-recognizer.cpp
new file mode 100644 (file)
index 0000000..cadad3a
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/event/events/pan-gesture-recognizer.h>
+
+// EXTERNAL INCLUDES
+#include <cmath>
+
+#include <dali/public-api/events/touch-point.h>
+
+#include <dali/integration-api/events/touch-event-integ.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/common/scene-impl.h>
+#include <dali/internal/event/events/pan-gesture-event.h>
+#include <dali/internal/event/events/gesture-requests.h>
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace
+{
+const float MINIMUM_MOTION_DISTANCE_BEFORE_PAN( 15.0f );
+const float MINIMUM_MOTION_DISTANCE_BEFORE_PAN_SQUARED( MINIMUM_MOTION_DISTANCE_BEFORE_PAN * MINIMUM_MOTION_DISTANCE_BEFORE_PAN );
+const float MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO( 2.0f / 3.0f );
+const unsigned long MAXIMUM_TIME_DIFF_ALLOWED( 500 );
+const unsigned long MINIMUM_TIME_BEFORE_THRESHOLD_ADJUSTMENTS( 100 );
+const unsigned int MINIMUM_MOTION_EVENTS_BEFORE_PAN(2);
+} // unnamed namespace
+
+PanGestureRecognizer::PanGestureRecognizer( Observer& observer, Vector2 screenSize, const PanGestureRequest& request, int32_t minimumDistance, int32_t minimumPanEvents )
+: GestureRecognizer( screenSize, Gesture::Pan ),
+  mObserver( observer ),
+  mState( Clear ),
+  mThresholdAdjustmentsRemaining( 0 ),
+  mThresholdTotalAdjustments( MINIMUM_MOTION_DISTANCE_BEFORE_PAN * MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO ),
+  mPrimaryTouchDownTime( 0 ),
+  mMinimumTouchesRequired( request.minTouches ),
+  mMaximumTouchesRequired( request.maxTouches ),
+  mMinimumDistanceSquared( MINIMUM_MOTION_DISTANCE_BEFORE_PAN_SQUARED ),
+  mMinimumMotionEvents( MINIMUM_MOTION_EVENTS_BEFORE_PAN ),
+  mMotionEvents( 0 )
+{
+  if ( minimumDistance >= 0 )
+  {
+    mMinimumDistanceSquared = minimumDistance * minimumDistance;
+
+    // Usually, we do not want to apply the threshold straight away, but phased over the first few pans
+    // Set our distance to threshold adjustments ratio here.
+    float fMinimumDistance = static_cast<float>( minimumDistance );
+    mThresholdTotalAdjustments = static_cast<unsigned int>( fMinimumDistance * MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO );
+  }
+
+  if ( minimumPanEvents >= 1 )
+  {
+    mMinimumMotionEvents = minimumPanEvents - 1; // Down is the first event
+  }
+}
+
+PanGestureRecognizer::~PanGestureRecognizer()
+{
+}
+
+void PanGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
+{
+  PointState::Type primaryPointState(event.points[0].GetState());
+
+  if (primaryPointState == PointState::INTERRUPTED)
+  {
+    if ( ( mState == Started ) || ( mState == Possible ) )
+    {
+      // If our pan had started and we are interrupted, then tell Core that pan is cancelled.
+      mTouchEvents.push_back(event);
+      SendPan(Gesture::Cancelled, event);
+    }
+    mState = Clear; // We should change our state to Clear.
+    mTouchEvents.clear();
+  }
+  else
+  {
+    switch (mState)
+    {
+      case Clear:
+      {
+        if ( ( primaryPointState == PointState::DOWN ) || ( primaryPointState == PointState::STATIONARY ) )
+        {
+          mPrimaryTouchDownLocation = event.points[0].GetScreenPosition();
+          mPrimaryTouchDownTime = event.time;
+          mMotionEvents = 0;
+          if (event.GetPointCount() == mMinimumTouchesRequired)
+          {
+            // We have satisfied the minimum touches required for a pan, tell core that a gesture may be possible and change our state accordingly.
+            mState = Possible;
+            SendPan(Gesture::Possible, event);
+          }
+
+          mTouchEvents.push_back(event);
+        }
+        break;
+      }
+
+      case Possible:
+      {
+        unsigned int pointCount(event.GetPointCount());
+        if ( (pointCount >= mMinimumTouchesRequired)&&(pointCount <= mMaximumTouchesRequired) )
+        {
+          if (primaryPointState == PointState::MOTION)
+          {
+            mTouchEvents.push_back(event);
+            mMotionEvents++;
+
+            Vector2 delta(event.points[0].GetScreenPosition() - mPrimaryTouchDownLocation);
+
+            if ( ( mMotionEvents >= mMinimumMotionEvents ) &&
+                 ( delta.LengthSquared() >= static_cast<float>( mMinimumDistanceSquared ) ) )
+            {
+              // If the touch point(s) have moved enough distance to be considered a pan, then tell Core that the pan gesture has started and change our state accordingly.
+              mState = Started;
+              SendPan(Gesture::Started, event);
+            }
+          }
+          else if (primaryPointState == PointState::UP)
+          {
+            Vector2 delta(event.points[0].GetScreenPosition() - mPrimaryTouchDownLocation);
+            if (delta.LengthSquared() >= static_cast<float>( mMinimumDistanceSquared ) )
+            {
+              SendPan(Gesture::Started, event);
+              mTouchEvents.push_back(event);
+              SendPan(Gesture::Finished, event);
+            }
+            else
+            {
+              // If we have lifted the primary touch point then tell core the pan is cancelled and change our state to Clear.
+              SendPan(Gesture::Cancelled, event);
+            }
+            mState = Clear;
+            mTouchEvents.clear();
+          }
+        }
+        else
+        {
+          // We do not satisfy pan conditions, tell Core our Gesture has been cancelled.
+          SendPan(Gesture::Cancelled, event);
+
+          if (pointCount == 1 && primaryPointState == PointState::UP)
+          {
+            // If we have lifted the primary touch point, then change our state to Clear...
+            mState = Clear;
+            mTouchEvents.clear();
+          }
+          else
+          {
+            // ...otherwise change it to Failed.
+            mState = Failed;
+          }
+        }
+        break;
+      }
+
+      case Started:
+      {
+        mTouchEvents.push_back(event);
+
+        unsigned int pointCount(event.GetPointCount());
+        if ( (pointCount >= mMinimumTouchesRequired)&&(pointCount <= mMaximumTouchesRequired) )
+        {
+          switch (primaryPointState)
+          {
+            case PointState::MOTION:
+              // Pan is continuing, tell Core.
+              SendPan(Gesture::Continuing, event);
+              break;
+
+            case PointState::UP:
+              // Pan is finally finished when our primary point is lifted, tell Core and change our state to Clear.
+              mState = Clear;
+              SendPan(Gesture::Finished, event);
+              mTouchEvents.clear();
+              break;
+
+            case PointState::STATIONARY:
+              if (pointCount == mMinimumTouchesRequired)
+              {
+                Integration::PointContainerConstIterator iter = event.points.begin() + 1; // We already know the state of the first point
+                for(; iter != event.points.end(); ++iter)
+                {
+                  if(iter->GetState() == PointState::UP)
+                  {
+                    // The number of touch points will be less than the minimum required.  Inform core and change our state to Finished.
+                    SendPan(Gesture::Finished, event);
+                    mState = Finished;
+                    break;
+                  }
+                }
+              }
+              break;
+
+            default:
+              break;
+          }
+        }
+        else
+        {
+          // We have gone outside of the pan requirements, inform Core that the gesture is finished.
+          SendPan(Gesture::Finished, event);
+
+          if (pointCount == 1 && primaryPointState == PointState::UP)
+          {
+            // If this was the primary point being released, then we change our state back to Clear...
+            mState = Clear;
+            mTouchEvents.clear();
+          }
+          else
+          {
+            // ...otherwise we change it to Finished.
+            mState = Finished;
+          }
+        }
+        break;
+      }
+
+      case Finished:
+      case Failed:
+      {
+        if (primaryPointState == PointState::UP)
+        {
+          // Change our state back to clear when the primary touch point is released.
+          mState = Clear;
+          mTouchEvents.clear();
+        }
+        break;
+      }
+    }
+  }
+}
+
+void PanGestureRecognizer::Update(const GestureRequest& request)
+{
+  const PanGestureRequest& pan = static_cast<const PanGestureRequest&>(request);
+
+  mMinimumTouchesRequired = pan.minTouches;
+  mMaximumTouchesRequired = pan.maxTouches;
+}
+
+void PanGestureRecognizer::SendPan(Gesture::State state, const Integration::TouchEvent& currentEvent)
+{
+  PanGestureEvent gesture(state);
+  gesture.currentPosition = currentEvent.points[0].GetScreenPosition();
+  gesture.numberOfTouches = currentEvent.GetPointCount();
+
+  if ( mTouchEvents.size() > 1 )
+  {
+    // Get the second last event in the queue, the last one is the current event
+    const Integration::TouchEvent& previousEvent( *( mTouchEvents.rbegin() + 1 ) );
+
+    Vector2 previousPosition( mPreviousPosition );
+    uint32_t previousTime( previousEvent.time );
+
+    // If we've just started then we want to remove the threshold from Core calculations.
+    if ( state == Gesture::Started )
+    {
+      previousPosition = mPrimaryTouchDownLocation;
+      previousTime = mPrimaryTouchDownTime;
+
+      // If it's a slow pan, we do not want to phase in the threshold over the first few pan-events
+      // A slow pan is defined as one that starts the specified number of milliseconds after the down-event
+      if ( ( currentEvent.time - previousTime ) > MINIMUM_TIME_BEFORE_THRESHOLD_ADJUSTMENTS )
+      {
+        mThresholdAdjustmentsRemaining = mThresholdTotalAdjustments;
+        mThresholdAdjustmentPerFrame = ( gesture.currentPosition - previousPosition ) / static_cast<float>( mThresholdTotalAdjustments );
+      }
+      else
+      {
+        mThresholdAdjustmentsRemaining = 0;
+        mThresholdAdjustmentPerFrame = Vector2::ZERO;
+      }
+    }
+
+    gesture.previousPosition = previousPosition;
+    gesture.timeDelta = currentEvent.time - previousTime;
+
+    // Apply the threshold with a phased approach
+    if ( mThresholdAdjustmentsRemaining > 0 )
+    {
+      --mThresholdAdjustmentsRemaining;
+      gesture.currentPosition -= mThresholdAdjustmentPerFrame * static_cast<float>( mThresholdAdjustmentsRemaining );
+    }
+
+    mPreviousPosition = gesture.currentPosition;
+  }
+  else
+  {
+    gesture.previousPosition = gesture.currentPosition;
+    gesture.timeDelta = 0;
+  }
+
+  gesture.time = currentEvent.time;
+
+  if( mScene )
+  {
+    // Create another handle so the recognizer cannot be destroyed during process function
+    GestureRecognizerPtr recognizerHandle = this;
+
+    mObserver.Process(*mScene, gesture);
+  }
+}
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/dali/internal/event/events/pan-gesture-recognizer.h b/dali/internal/event/events/pan-gesture-recognizer.h
new file mode 100644 (file)
index 0000000..506ab88
--- /dev/null
@@ -0,0 +1,126 @@
+#ifndef DALI_INTERNAL_EVENT_PAN_GESTURE_DETECTOR_H
+#define DALI_INTERNAL_EVENT_PAN_GESTURE_DETECTOR_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <cstdint> // uint32_t
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/events/gesture-recognizer.h>
+#include <dali/internal/event/events/pan-gesture-event.h>
+
+namespace Dali
+{
+
+namespace Integration
+{
+class Core;
+struct TouchEvent;
+
+}
+
+namespace Internal
+{
+
+struct PanGestureRequest;
+/**
+ * When given a set of touch events, this detector attempts to determine if a pan gesture has taken place.
+ */
+class PanGestureRecognizer : public GestureRecognizer
+{
+public:
+
+  using Observer = RecognizerObserver<PanGestureEvent>;
+
+  /**
+   * Constructor
+   * @param[in]  screenSize  The size of the screen.
+   * @param[in]  request     The details of the request.
+   */
+  PanGestureRecognizer( Observer& observer, Vector2 screenSize, const PanGestureRequest& request, int32_t minimumDistance, int32_t minimumPanEvents);
+
+  /**
+   * Virtual destructor.
+   */
+  virtual ~PanGestureRecognizer();
+
+public:
+
+  /**
+   * @copydoc Dali::Internal::GestureDetector::SendEvent(const Integration::TouchEvent&)
+   */
+  virtual void SendEvent(const Integration::TouchEvent& event);
+
+  /**
+   * @copydoc Dali::Internal::GestureDetector::Update(const Integration::GestureRequest&)
+   */
+  virtual void Update(const GestureRequest& request);
+
+private:
+
+  /**
+   * Emits the pan gesture event (performs some smoothing operation).
+   * @param[in]  state         The state of the pan.
+   * @param[in]  currentEvent  The latest touch event.
+   */
+  void SendPan(Gesture::State state, const Integration::TouchEvent& currentEvent);
+
+private:
+
+  // Reference to the gesture processor for this recognizer
+  Observer& mObserver;
+
+  /**
+   * Internal state machine.
+   */
+  enum State
+  {
+    Clear,    ///< No gesture detected.
+    Possible, ///< The current touch event data suggests that a gesture is possible.
+    Started,  ///< A gesture has been detected.
+    Finished, ///< A previously started pan gesture has finished.
+    Failed,   ///< Current touch event data suggests a pan gesture is not possible.
+  };
+
+  State mState; ///< The current state of the detector.
+  std::vector<Integration::TouchEvent> mTouchEvents;     ///< A container of all touch events after an initial down event.
+
+  Vector2 mPrimaryTouchDownLocation;    ///< The initial touch down point.
+  Vector2 mThresholdAdjustmentPerFrame; ///< The adjustment per frame at the start of a slow pan.
+  Vector2 mPreviousPosition;            ///< The previous position.
+
+  unsigned int mThresholdAdjustmentsRemaining; ///< No. of threshold adjustments still to apply (for a slow-pan).
+  unsigned int mThresholdTotalAdjustments;     ///< The total number of adjustments required.
+
+  uint32_t mPrimaryTouchDownTime;       ///< The initial touch down time.
+  unsigned int mMinimumTouchesRequired; ///< The minimum touches required before a pan should be emitted.
+  unsigned int mMaximumTouchesRequired; ///< The maximum touches after which a pan should not be emitted.
+
+  unsigned int mMinimumDistanceSquared; ///< The minimum distance squared before pan should start.
+  unsigned int mMinimumMotionEvents;    ///< The minimum motion events before pan should start.
+  unsigned int mMotionEvents;           ///< The motion events received so far (before pan is emitted).
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_EVENT_PAN_GESTURE_DETECTOR_BASE_H
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
  */
 
 // CLASS HEADER
-#include <dali/integration-api/events/pinch-gesture-event.h>
+#include <dali/internal/event/events/pinch-gesture-event.h>
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
@@ -24,7 +24,7 @@
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 PinchGestureEvent::PinchGestureEvent(Gesture::State state)
@@ -39,6 +39,6 @@ PinchGestureEvent::~PinchGestureEvent()
 {
 }
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_PINCH_GESTURE_EVENT_H__
-#define __DALI_INTEGRATION_PINCH_GESTURE_EVENT_H__
+#ifndef DALI_INTERNAL_EVENT_PINCH_GESTURE_EVENT_H
+#define DALI_INTERNAL_EVENT_PINCH_GESTURE_EVENT_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // INTERNAL INCLUDES
-#include <dali/integration-api/events/gesture-event.h>
+#include <dali/internal/event/events/gesture-event.h>
 #include <dali/public-api/math/vector2.h>
 
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 /**
@@ -38,7 +38,7 @@ namespace Integration
  * - Finished:   If after a pinch, the user lifts their finger(s).
  * - Cancelled:  If there is a system interruption.
  */
-struct DALI_CORE_API PinchGestureEvent : public GestureEvent
+struct PinchGestureEvent : public GestureEvent
 {
   // Construction & Destruction
 
@@ -76,4 +76,4 @@ struct DALI_CORE_API PinchGestureEvent : public GestureEvent
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_PINCH_GESTURE_EVENT_H__
+#endif // DALI_INTERNAL_EVENT_PINCH_GESTURE_EVENT_H
index 21c362c..8840f5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/public-api/actors/actor.h>
 #include <dali/public-api/events/pinch-gesture.h>
 #include <dali/public-api/math/vector2.h>
-#include <dali/integration-api/events/pinch-gesture-event.h>
-#include <dali/integration-api/gesture-manager.h>
+#include <dali/internal/event/events/pinch-gesture-event.h>
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/common/scene-impl.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
+#include <dali/internal/event/events/pinch-gesture-recognizer.h>
+#include <dali/internal/event/events/gesture-requests.h>
 
 namespace Dali
 {
@@ -50,7 +51,7 @@ namespace
 void EmitPinchSignal(
     Actor* actor,
     const GestureDetectorContainer& gestureDetectors,
-    const Integration::PinchGestureEvent& pinchEvent,
+    const PinchGestureEvent& pinchEvent,
     Vector2 localCenter)
 {
   PinchGesture pinch(pinchEvent.state);
@@ -100,12 +101,12 @@ struct IsNotAttachedFunctor
 
 } // unnamed namespace
 
-PinchGestureProcessor::PinchGestureProcessor( Integration::GestureManager& gestureManager )
+PinchGestureProcessor::PinchGestureProcessor()
 : GestureProcessor( Gesture::Pinch ),
-  mGestureManager(gestureManager),
-  mGestureDetectors(),
+  mPinchGestureDetectors(),
   mCurrentPinchEmitters(),
-  mCurrentPinchEvent(NULL)
+  mCurrentPinchEvent(NULL),
+  mMinimumPinchDistance(-1.0f)
 {
 }
 
@@ -113,7 +114,18 @@ PinchGestureProcessor::~PinchGestureProcessor()
 {
 }
 
-void PinchGestureProcessor::Process( Scene& scene, const Integration::PinchGestureEvent& pinchEvent )
+void PinchGestureProcessor::SetMinimumPinchDistance( float value )
+{
+  mMinimumPinchDistance = value;
+
+  if( mGestureRecognizer )
+  {
+    PinchGestureRecognizer* pinchRecognizer = dynamic_cast<PinchGestureRecognizer*>(mGestureRecognizer.Get());
+    pinchRecognizer->SetMinimumPinchDistance(value);
+  }
+}
+
+void PinchGestureProcessor::Process( Scene& scene, const PinchGestureEvent& pinchEvent )
 {
   switch ( pinchEvent.state )
   {
@@ -198,16 +210,16 @@ void PinchGestureProcessor::Process( Scene& scene, const Integration::PinchGestu
   }
 }
 
-void PinchGestureProcessor::AddGestureDetector( PinchGestureDetector* gestureDetector )
+void PinchGestureProcessor::AddGestureDetector( PinchGestureDetector* gestureDetector, Scene& scene )
 {
-  bool registerWithAdaptor(mGestureDetectors.empty());
+  bool createRecognizer(mPinchGestureDetectors.empty());
 
-  mGestureDetectors.push_back(gestureDetector);
+  mPinchGestureDetectors.push_back(gestureDetector);
 
-  if (registerWithAdaptor)
+  if (createRecognizer)
   {
-    Integration::GestureRequest request(Gesture::Pinch);
-    mGestureManager.Register(request);
+    Size size = scene.GetSize();
+    mGestureRecognizer = new PinchGestureRecognizer( *this, Vector2(size.width, size.height), mMinimumPinchDistance);
   }
 }
 
@@ -227,16 +239,15 @@ void PinchGestureProcessor::RemoveGestureDetector( PinchGestureDetector* gesture
   }
 
   // Find the detector...
-  PinchGestureDetectorContainer::iterator endIter = std::remove( mGestureDetectors.begin(), mGestureDetectors.end(), gestureDetector );
-  DALI_ASSERT_DEBUG( endIter != mGestureDetectors.end() );
+  PinchGestureDetectorContainer::iterator endIter = std::remove( mPinchGestureDetectors.begin(), mPinchGestureDetectors.end(), gestureDetector );
+  DALI_ASSERT_DEBUG( endIter != mPinchGestureDetectors.end() );
 
   // ...and remove it
-  mGestureDetectors.erase(endIter, mGestureDetectors.end());
+  mPinchGestureDetectors.erase(endIter, mPinchGestureDetectors.end());
 
-  if (mGestureDetectors.empty())
+  if (mPinchGestureDetectors.empty())
   {
-    Integration::GestureRequest request(Gesture::Pinch);
-    mGestureManager.Unregister(request);
+    mGestureRecognizer.Detach();
   }
 }
 
index f9d147b..3bbd75d 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_PINCH_GESTURE_EVENT_PROCESSOR_H__
-#define __DALI_INTERNAL_PINCH_GESTURE_EVENT_PROCESSOR_H__
+#ifndef DALI_INTERNAL_PINCH_GESTURE_EVENT_PROCESSOR_H
+#define DALI_INTERNAL_PINCH_GESTURE_EVENT_PROCESSOR_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 namespace Dali
 {
 
-namespace Integration
-{
-class GestureManager;
-struct GestureEvent;
-struct PinchGestureEvent;
-}
-
 namespace Internal
 {
 
 class Scene;
 class Stage;
 
+struct PinchGestureEvent;
+
 /**
  * Pinch Gesture Event Processing:
  *
@@ -49,7 +44,7 @@ class Stage;
  * The above is only checked when our gesture starts. We continue sending the pinch gesture to this
  * detector until the pinch ends or is cancelled.
  */
-class PinchGestureProcessor : public GestureProcessor
+class PinchGestureProcessor : public GestureProcessor, public RecognizerObserver<PinchGestureEvent>
 {
 public:
 
@@ -57,7 +52,7 @@ public:
    * Create a pinch gesture processor.
    * @param[in] gestureManager The gesture manager
    */
-  PinchGestureProcessor( Integration::GestureManager& gestureManager );
+  PinchGestureProcessor();
 
   /**
    * Non-virtual destructor; PinchGestureProcessor is not a base class
@@ -67,11 +62,17 @@ public:
 public: // To be called by GestureEventProcessor
 
   /**
+   * This method sets the minimum distance to start a pinch
+   * @param[in] value The distance in pixels
+   */
+  void SetMinimumPinchDistance( float value );
+
+  /**
    * This method is called whenever a pinch gesture event occurs.
    * @param[in] scene The scene the pinch gesture event occurs in.
    * @param[in] pinchEvent The event that has occurred.
    */
-  void Process( Scene& scene, const Integration::PinchGestureEvent& pinchEvent );
+  void Process( Scene& scene, const PinchGestureEvent& pinchEvent );
 
   /**
    * Adds a gesture detector to this gesture processor.
@@ -79,7 +80,7 @@ public: // To be called by GestureEventProcessor
    * gesture with the adaptor.
    * @param[in]  gestureDetector  The gesture detector being added.
    */
-  void AddGestureDetector(PinchGestureDetector* gestureDetector);
+  void AddGestureDetector(PinchGestureDetector* gestureDetector, Scene& scene);
 
   /**
    * Removes the specified gesture detector from this gesture processor.  If, after removing this
@@ -122,16 +123,17 @@ private:
 
 private:
 
-  Integration::GestureManager& mGestureManager;
-  PinchGestureDetectorContainer mGestureDetectors;
+  PinchGestureDetectorContainer mPinchGestureDetectors;
   GestureDetectorContainer mCurrentPinchEmitters;
   RenderTaskPtr mCurrentRenderTask;
 
-  const Integration::PinchGestureEvent* mCurrentPinchEvent; ///< Pointer to current PinchEvent, used when calling ProcessAndEmit()
+  const PinchGestureEvent* mCurrentPinchEvent; ///< Pointer to current PinchEvent, used when calling ProcessAndEmit()
+
+  float mMinimumPinchDistance;
 };
 
 } // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_PINCH_GESTURE_EVENT_PROCESSOR_H__
+#endif // DALI_INTERNAL_PINCH_GESTURE_EVENT_PROCESSOR_H
diff --git a/dali/internal/event/events/pinch-gesture-recognizer.cpp b/dali/internal/event/events/pinch-gesture-recognizer.cpp
new file mode 100644 (file)
index 0000000..6dde864
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/event/events/pinch-gesture-recognizer.h>
+
+// EXTERNAL INCLUDES
+#include <cmath>
+
+#include <dali/public-api/events/touch-point.h>
+#include <dali/public-api/math/vector2.h>
+
+#include <dali/internal/event/events/pinch-gesture-event.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/internal/event/common/scene-impl.h>
+
+// INTERNAL INCLUDES
+
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace
+{
+const unsigned int MINIMUM_TOUCH_EVENTS_REQUIRED = 4;
+const unsigned int MINIMUM_TOUCH_EVENTS_REQUIRED_AFTER_START = 4;
+
+const float MINIMUM_DISTANCE_DELTA_DIVISOR = 85.0f;
+
+inline float GetDistance(const Integration::Point& point1, const Integration::Point& point2)
+{
+  Vector2 vector(point1.GetScreenPosition() - point2.GetScreenPosition());
+  return vector.Length();
+}
+
+inline Vector2 GetCenterPoint(const Integration::Point& point1, const Integration::Point& point2)
+{
+  return Vector2(point1.GetScreenPosition() + point2.GetScreenPosition()) * 0.5f;
+}
+
+} // unnamed namespace
+
+PinchGestureRecognizer::PinchGestureRecognizer( Observer& observer, Vector2 screenSize, float minimumPinchDistance )
+: GestureRecognizer( screenSize, Gesture::Pinch ),
+  mObserver( observer ),
+  mState( Clear ),
+  mTouchEvents(),
+  mStartingDistance( 0.0f )
+{
+  SetMinimumPinchDistance( minimumPinchDistance );
+}
+
+PinchGestureRecognizer::~PinchGestureRecognizer()
+{
+}
+
+void PinchGestureRecognizer::SetMinimumPinchDistance(float value)
+{
+  mMinimumDistanceDelta = value >= 0.0f ? value : (mScreenSize.height / MINIMUM_DISTANCE_DELTA_DIVISOR);
+}
+
+void PinchGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
+{
+  int pointCount = event.GetPointCount();
+
+  switch (mState)
+  {
+    case Clear:
+    {
+      if (pointCount == 2)
+      {
+        // Change state to possible as we have two touch points.
+        mState = Possible;
+        mTouchEvents.push_back(event);
+      }
+      break;
+    }
+
+    case Possible:
+    {
+      if (pointCount != 2)
+      {
+        // We no longer have two touch points so change state back to Clear.
+        mState = Clear;
+        mTouchEvents.clear();
+      }
+      else
+      {
+        const Integration::Point& currentPoint1 = event.points[0];
+        const Integration::Point& currentPoint2 = event.points[1];
+
+        if (currentPoint1.GetState() == PointState::UP || currentPoint2.GetState() == PointState::UP)
+        {
+          // One of our touch points has an Up event so change our state back to Clear.
+          mState = Clear;
+          mTouchEvents.clear();
+        }
+        else
+        {
+          mTouchEvents.push_back(event);
+
+          // We can only determine a pinch after a certain number of touch points have been collected.
+          if (mTouchEvents.size() >= MINIMUM_TOUCH_EVENTS_REQUIRED)
+          {
+            const Integration::Point& firstPoint1 = mTouchEvents[0].points[0];
+            const Integration::Point& firstPoint2 = mTouchEvents[0].points[1];
+
+            float firstDistance = GetDistance(firstPoint1, firstPoint2);
+            float currentDistance = GetDistance(currentPoint1, currentPoint2);
+            float distanceChanged = firstDistance - currentDistance;
+
+            // Check if distance has changed enough
+            if (fabsf(distanceChanged) > mMinimumDistanceDelta)
+            {
+              // Remove the first few events from the vector otherwise values are exaggerated
+              mTouchEvents.erase(mTouchEvents.begin(), mTouchEvents.end() - MINIMUM_TOUCH_EVENTS_REQUIRED_AFTER_START);
+
+              if ( !mTouchEvents.empty() )
+              {
+                mStartingDistance = GetDistance(mTouchEvents.begin()->points[0], mTouchEvents.begin()->points[1]);
+
+                // Send pinch started
+                SendPinch(Gesture::Started, event);
+
+                mState = Started;
+              }
+
+              mTouchEvents.clear();
+            }
+
+            if (mState == Possible)
+            {
+              // No pinch, so restart detection
+              mState = Clear;
+              mTouchEvents.clear();
+            }
+          }
+        }
+      }
+      break;
+    }
+
+    case Started:
+    {
+      if (pointCount != 2)
+      {
+        // Send pinch finished event
+        SendPinch(Gesture::Finished, event);
+
+        mState = Clear;
+        mTouchEvents.clear();
+      }
+      else
+      {
+        const Integration::Point& currentPoint1 = event.points[0];
+        const Integration::Point& currentPoint2 = event.points[1];
+
+        if (currentPoint1.GetState() == PointState::UP || currentPoint2.GetState() == PointState::UP)
+        {
+          mTouchEvents.push_back(event);
+          // Send pinch finished event
+          SendPinch(Gesture::Finished, event);
+
+          mState = Clear;
+          mTouchEvents.clear();
+        }
+        else
+        {
+          mTouchEvents.push_back(event);
+
+          if (mTouchEvents.size() >= MINIMUM_TOUCH_EVENTS_REQUIRED_AFTER_START)
+          {
+            // Send pinch continuing
+            SendPinch(Gesture::Continuing, event);
+
+            mTouchEvents.clear();
+          }
+        }
+      }
+      break;
+    }
+  }
+}
+
+void PinchGestureRecognizer::Update(const GestureRequest& request)
+{
+  // Nothing to do.
+}
+
+void PinchGestureRecognizer::SendPinch(Gesture::State state, const Integration::TouchEvent& currentEvent)
+{
+  PinchGestureEvent gesture(state);
+
+  if ( !mTouchEvents.empty() )
+  {
+    const Integration::TouchEvent& firstEvent = mTouchEvents[0];
+
+    // Assert if we have been holding TouchEvents that do not have 2 points
+    DALI_ASSERT_DEBUG( firstEvent.GetPointCount() == 2 );
+
+    // We should use the current event in our calculations unless it does not have two points.
+    // If it does not have two points, then we should use the last point in mTouchEvents.
+    Integration::TouchEvent event( currentEvent );
+    if ( event.GetPointCount() != 2 )
+    {
+      event = *mTouchEvents.rbegin();
+    }
+
+    const Integration::Point& firstPoint1( firstEvent.points[0] );
+    const Integration::Point& firstPoint2( firstEvent.points[1] );
+    const Integration::Point& currentPoint1( event.points[0] );
+    const Integration::Point& currentPoint2( event.points[1] );
+
+    float firstDistance = GetDistance(firstPoint1, firstPoint2);
+    float currentDistance = GetDistance(currentPoint1, currentPoint2);
+    gesture.scale = currentDistance / mStartingDistance;
+
+    float distanceDelta = fabsf(firstDistance - currentDistance);
+    float timeDelta = static_cast<float> ( currentEvent.time - firstEvent.time );
+    gesture.speed = ( distanceDelta / timeDelta ) * 1000.0f;
+
+    gesture.centerPoint = GetCenterPoint(currentPoint1, currentPoint2);
+  }
+  else
+  {
+    // Something has gone wrong, just cancel the gesture.
+    gesture.state = Gesture::Cancelled;
+  }
+
+  gesture.time = currentEvent.time;
+
+  if( mScene )
+  {
+    // Create another handle so the recognizer cannot be destroyed during process function
+    GestureRecognizerPtr recognizerHandle = this;
+
+    mObserver.Process(*mScene, gesture);
+  }
+}
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/dali/internal/event/events/pinch-gesture-recognizer.h b/dali/internal/event/events/pinch-gesture-recognizer.h
new file mode 100644 (file)
index 0000000..5a614b1
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef DALI_INTERNAL_EVENT_PINCH_GESTURE_RECOGNIZER_H
+#define DALI_INTERNAL_EVENT_PINCH_GESTURE_RECOGNIZER_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/events/gesture-recognizer.h>
+#include <dali/internal/event/events/pinch-gesture-event.h>
+
+namespace Dali
+{
+
+namespace Integration
+{
+struct TouchEvent;
+}
+
+namespace Internal
+{
+
+/**
+ * When given a set of touch events, this detector attempts to determine if a pinch gesture has taken place.
+ */
+class PinchGestureRecognizer : public GestureRecognizer
+{
+public:
+
+  using Observer = RecognizerObserver<PinchGestureEvent>;
+
+  /**
+   * Constructor
+   * @param[in] screenSize The size of the screen.
+   * @param[in] minimumPinchDistance in pixels
+   */
+  PinchGestureRecognizer(Observer& observer, Vector2 screenSize, float minimumPinchDistance);
+
+  /**
+   * Virtual destructor.
+   */
+  virtual ~PinchGestureRecognizer();
+
+public:
+
+  void SetMinimumPinchDistance(float value);
+
+  /**
+   * @copydoc Dali::Internal::GestureDetector::SendEvent(const Integration::TouchEvent&)
+   */
+  virtual void SendEvent(const Integration::TouchEvent& event);
+
+  /**
+   * @copydoc Dali::Internal::GestureDetector::Update(const Integration::GestureRequest&)
+   */
+  virtual void Update(const GestureRequest& request);
+
+private:
+
+  /**
+   * Emits the pinch gesture event to the core.
+   * @param[in]  state         The state of the pinch (whether it's starting, continuing or finished).
+   * @param[in]  currentEvent  The latest touch event.
+   */
+  void SendPinch(Gesture::State state, const Integration::TouchEvent& currentEvent);
+
+private:
+
+  // Reference to the gesture processor for this recognizer
+  Observer& mObserver;
+
+  /**
+   * Internal state machine.
+   */
+  enum State
+  {
+    Clear,    ///< No gesture detected.
+    Possible, ///< The current touch event data suggests that a gesture is possible.
+    Started,  ///< A gesture has been detected.
+  };
+
+  State mState; ///< The current state of the detector.
+  std::vector<Integration::TouchEvent> mTouchEvents; ///< The touch events since initial touch down.
+
+  float mMinimumDistanceDelta; ///< The minimum distance before a pinch is applicable.
+
+  float mStartingDistance; ///< The distance between the two touch points when the pinch is first detected.
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_EVENT_PINCH_GESTURE_RECOGNIZER_H
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // CLASS HEADER
-#include <dali/integration-api/events/tap-gesture-event.h>
+#include <dali/internal/event/events/tap-gesture-event.h>
 
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 TapGestureEvent::TapGestureEvent( Gesture::State state )
@@ -35,6 +35,6 @@ TapGestureEvent::~TapGestureEvent()
 {
 }
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTEGRATION_TAP_GESTURE_H__
-#define __DALI_INTEGRATION_TAP_GESTURE_H__
+#ifndef DALI_INTERNAL_EVENT_TAP_GESTURE_H
+#define DALI_INTERNAL_EVENT_TAP_GESTURE_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // INTERNAL INCLUDES
-#include <dali/integration-api/events/gesture-event.h>
 #include <dali/public-api/math/vector2.h>
+#include <dali/internal/event/events/gesture-event.h>
 
 namespace Dali
 {
 
-namespace Integration
+namespace Internal
 {
 
 /**
@@ -40,7 +40,7 @@ namespace Integration
  *
  * A Started state will be ignored if a Possible state does not precede it.
  */
-struct DALI_CORE_API TapGestureEvent : public GestureEvent
+struct TapGestureEvent : public GestureEvent
 {
   // Construction & Destruction
 
@@ -76,8 +76,8 @@ struct DALI_CORE_API TapGestureEvent : public GestureEvent
   Vector2 point;
 };
 
-} // namespace Integration
+} // namespace Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTEGRATION_TAP_GESTURE_H__
+#endif // DALI_INTERNAL_EVENT_TAP_GESTURE_H
index 9d3cbd8..65fc8fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/events/tap-gesture.h>
 #include <dali/public-api/math/vector2.h>
-#include <dali/integration-api/events/tap-gesture-event.h>
-#include <dali/integration-api/gesture-manager.h>
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/actors/actor-impl.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/internal/event/common/scene-impl.h>
+#include <dali/internal/event/events/tap-gesture-recognizer.h>
+#include <dali/internal/event/events/gesture-requests.h>
+#include <dali/internal/event/events/tap-gesture-event.h>
 
 namespace Dali
 {
@@ -52,7 +53,7 @@ namespace
 void EmitTapSignal(
   Actor* actor,
   const GestureDetectorContainer& gestureDetectors,
-  const Integration::TapGestureEvent& tapEvent,
+  const TapGestureEvent& tapEvent,
   Vector2 localPoint)
 {
   TapGesture tap;
@@ -72,10 +73,9 @@ void EmitTapSignal(
 
 } // unnamed namespace
 
-TapGestureProcessor::TapGestureProcessor( Integration::GestureManager& gestureManager)
+TapGestureProcessor::TapGestureProcessor()
 : GestureProcessor( Gesture::Tap ),
-  mGestureManager( gestureManager ),
-  mGestureDetectors(),
+  mTapGestureDetectors(),
   mMinTapsRequired( 1 ),
   mMaxTapsRequired( 1 ),
   mMinTouchesRequired( 1 ),
@@ -89,7 +89,7 @@ TapGestureProcessor::~TapGestureProcessor()
 {
 }
 
-void TapGestureProcessor::Process( Scene& scene, const Integration::TapGestureEvent& tapEvent )
+void TapGestureProcessor::Process( Scene& scene, const TapGestureEvent& tapEvent )
 {
   switch ( tapEvent.state )
   {
@@ -155,11 +155,11 @@ void TapGestureProcessor::Process( Scene& scene, const Integration::TapGestureEv
   }
 }
 
-void TapGestureProcessor::AddGestureDetector( TapGestureDetector* gestureDetector )
+void TapGestureProcessor::AddGestureDetector( TapGestureDetector* gestureDetector, Scene& scene )
 {
-  bool firstRegistration(mGestureDetectors.empty());
+  bool firstRegistration(mTapGestureDetectors.empty());
 
-  mGestureDetectors.push_back(gestureDetector);
+  mTapGestureDetectors.push_back(gestureDetector);
 
   const unsigned int minTapsRequired = gestureDetector->GetMinimumTapsRequired();
   const unsigned int maxTapsRequired = gestureDetector->GetMaximumTapsRequired();
@@ -176,12 +176,14 @@ void TapGestureProcessor::AddGestureDetector( TapGestureDetector* gestureDetecto
     mMaxTapsRequired = maxTapsRequired;
     mMinTouchesRequired = mMaxTouchesRequired = touchesRequired;
 
-    Integration::TapGestureRequest request;
+    TapGestureRequest request;
     request.minTaps = mMinTapsRequired;
     request.maxTaps = mMaxTapsRequired;
     request.minTouches = mMinTouchesRequired;
     request.maxTouches = mMaxTouchesRequired;
-    mGestureManager.Register(request);
+
+    Size size = scene.GetSize();
+    mGestureRecognizer = new TapGestureRecognizer(*this, Vector2(size.width, size.height), static_cast<const TapGestureRequest&>(request));
   }
   else
   {
@@ -199,12 +201,13 @@ void TapGestureProcessor::AddGestureDetector( TapGestureDetector* gestureDetecto
     if ( (minTaps != mMinTapsRequired)||(maxTaps != mMaxTapsRequired) ||
          (minTouches != mMinTouchesRequired)||(maxTouches != mMaxTouchesRequired) )
     {
-      Integration::TapGestureRequest request;
+      TapGestureRequest request;
       request.minTaps = mMinTapsRequired = minTaps;
       request.maxTaps = mMaxTapsRequired = maxTaps;
       request.minTouches = mMinTouchesRequired = minTouches;
       request.maxTouches = mMaxTouchesRequired = maxTouches;
-      mGestureManager.Update(request);
+
+      mGestureRecognizer->Update(request);
     }
   }
 }
@@ -212,16 +215,15 @@ void TapGestureProcessor::AddGestureDetector( TapGestureDetector* gestureDetecto
 void TapGestureProcessor::RemoveGestureDetector( TapGestureDetector* gestureDetector )
 {
   // Find detector ...
-  TapGestureDetectorContainer::iterator endIter = std::remove( mGestureDetectors.begin(), mGestureDetectors.end(), gestureDetector );
-  DALI_ASSERT_DEBUG( endIter != mGestureDetectors.end() );
+  TapGestureDetectorContainer::iterator endIter = std::remove( mTapGestureDetectors.begin(), mTapGestureDetectors.end(), gestureDetector );
+  DALI_ASSERT_DEBUG( endIter != mTapGestureDetectors.end() );
 
   // ... and remove it
-  mGestureDetectors.erase( endIter, mGestureDetectors.end() );
+  mTapGestureDetectors.erase( endIter, mTapGestureDetectors.end() );
 
-  if ( mGestureDetectors.empty() )
+  if ( mTapGestureDetectors.empty() )
   {
-    Integration::GestureRequest request(Gesture::Tap);
-    mGestureManager.Unregister(request);
+    mGestureRecognizer.Detach();
 
     ResetActor();
   }
@@ -233,7 +235,7 @@ void TapGestureProcessor::RemoveGestureDetector( TapGestureDetector* gestureDete
 
 void TapGestureProcessor::GestureDetectorUpdated( TapGestureDetector* gestureDetector )
 {
-  DALI_ASSERT_DEBUG(find(mGestureDetectors.begin(), mGestureDetectors.end(), gestureDetector) != mGestureDetectors.end());
+  DALI_ASSERT_DEBUG(find(mTapGestureDetectors.begin(), mTapGestureDetectors.end(), gestureDetector) != mTapGestureDetectors.end());
 
   const unsigned int minTapsRequired = gestureDetector->GetMinimumTapsRequired();
   const unsigned int maxTapsRequired = gestureDetector->GetMaximumTapsRequired();
@@ -245,14 +247,14 @@ void TapGestureProcessor::GestureDetectorUpdated( TapGestureDetector* gestureDet
 
 void TapGestureProcessor::UpdateDetection()
 {
-  DALI_ASSERT_DEBUG(!mGestureDetectors.empty());
+  DALI_ASSERT_DEBUG(!mTapGestureDetectors.empty());
 
   unsigned int minTaps = UINT_MAX;
   unsigned int maxTaps = 0;
   unsigned int minTouches = UINT_MAX;
   unsigned int maxTouches = 0;
 
-  for ( TapGestureDetectorContainer::iterator iter = mGestureDetectors.begin(), endIter = mGestureDetectors.end(); iter != endIter; ++iter )
+  for ( TapGestureDetectorContainer::iterator iter = mTapGestureDetectors.begin(), endIter = mTapGestureDetectors.end(); iter != endIter; ++iter )
   {
     TapGestureDetector* detector(*iter);
 
@@ -272,12 +274,13 @@ void TapGestureProcessor::UpdateDetection()
   if ( (minTaps != mMinTapsRequired)||(maxTaps != mMaxTapsRequired) ||
        (minTouches != mMinTouchesRequired)||(maxTouches != mMaxTouchesRequired) )
   {
-    Integration::TapGestureRequest request;
+    TapGestureRequest request;
     request.minTaps = mMinTapsRequired = minTaps;
     request.maxTaps = mMaxTapsRequired = maxTaps;
     request.minTouches = mMinTouchesRequired = minTouches;
     request.maxTouches = mMaxTouchesRequired = maxTouches;
-    mGestureManager.Update(request);
+
+    mGestureRecognizer->Update(request);
   }
 }
 
index f391987..df64cb7 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_TAP_GESTURE_EVENT_PROCESSOR_H__
-#define __DALI_INTERNAL_TAP_GESTURE_EVENT_PROCESSOR_H__
+#ifndef DALI_INTERNAL_TAP_GESTURE_EVENT_PROCESSOR_H
+#define DALI_INTERNAL_TAP_GESTURE_EVENT_PROCESSOR_H
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 namespace Dali
 {
 
-namespace Integration
-{
-class GestureManager;
-struct GestureEvent;
-struct TapGestureEvent;
-}
-
 namespace Internal
 {
 
@@ -40,6 +33,9 @@ class Scene;
 class Stage;
 class Actor;
 
+struct GestureEvent;
+struct TapGestureEvent;
+
 /**
  * Tap Gesture Event Processing:
  *
@@ -47,7 +43,7 @@ class Actor;
  * - Find the actor that requires a tap where the tap occurred.
  * - Emit the gesture if the tap gesture event satisfies the detector conditions.
  */
-class TapGestureProcessor : public GestureProcessor
+class TapGestureProcessor : public GestureProcessor, public RecognizerObserver<TapGestureEvent>
 {
 public:
 
@@ -55,7 +51,7 @@ public:
    * Create a tap gesture processor.
    * @param[in] gestureManager The gesture manager.
    */
-  TapGestureProcessor( Integration::GestureManager& gestureManager );
+  TapGestureProcessor();
 
   /**
    * Non-virtual destructor; TapGestureProcessor is not a base class
@@ -69,7 +65,7 @@ public: // To be called by GestureEventProcessor
    * @param[in] scene The scene the tap gesture event occurs in.
    * @param[in] tapEvent The event that has occurred.
    */
-  void Process( Scene& scene, const Integration::TapGestureEvent& tapEvent);
+  void Process( Scene& scene, const TapGestureEvent& event);
 
   /**
    * Adds a gesture detector to this gesture processor.
@@ -77,7 +73,7 @@ public: // To be called by GestureEventProcessor
    * gesture with the adaptor.
    * @param[in]  gestureDetector  The gesture detector being added.
    */
-  void AddGestureDetector(TapGestureDetector* gestureDetector);
+  void AddGestureDetector(TapGestureDetector* gestureDetector, Scene& scene);
 
   /**
    * Removes the specified gesture detector from this gesture processor.  If, after removing this
@@ -126,8 +122,7 @@ private:
 
 private:
 
-  Integration::GestureManager& mGestureManager;
-  TapGestureDetectorContainer mGestureDetectors;
+  TapGestureDetectorContainer mTapGestureDetectors;
 
   unsigned int mMinTapsRequired;
   unsigned int mMaxTapsRequired;
@@ -135,7 +130,7 @@ private:
   unsigned int mMaxTouchesRequired;
 
   ActorObserver mCurrentTapActor; ///< Observer for the current gesture actor
-  const Integration::TapGestureEvent* mCurrentTapEvent; ///< Pointer to current TapEvent, used when calling ProcessAndEmit()
+  const TapGestureEvent* mCurrentTapEvent; ///< Pointer to current TapEvent, used when calling ProcessAndEmit()
   bool mPossibleProcessed; ///< Indication of whether we've processed a touch down for this gestuee
 };
 
@@ -143,4 +138,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_TAP_GESTURE_EVENT_PROCESSOR_H__
+#endif // DALI_INTERNAL_TAP_GESTURE_EVENT_PROCESSOR_H
diff --git a/dali/internal/event/events/tap-gesture-recognizer.cpp b/dali/internal/event/events/tap-gesture-recognizer.cpp
new file mode 100644 (file)
index 0000000..1129d9a
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/event/events/tap-gesture-recognizer.h>
+
+// EXTERNAL INCLUDES
+#include <cmath>
+
+#include <dali/public-api/math/vector2.h>
+
+#include <dali/integration-api/events/touch-event-integ.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/events/gesture-requests.h>
+#include <dali/internal/event/common/scene-impl.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace
+{
+// TODO: Set these according to DPI
+const float MAXIMUM_MOTION_ALLOWED = 20.0f;
+const unsigned long MAXIMUM_TIME_ALLOWED = 500u;
+} // unnamed namespace
+
+TapGestureRecognizer::TapGestureRecognizer( Observer& observer, Vector2 screenSize, const TapGestureRequest& request)
+: GestureRecognizer( screenSize, Gesture::Tap ),
+  mObserver(observer),
+  mState(Clear),
+  mMinimumTapsRequired(request.minTaps),
+  mMaximumTapsRequired(request.maxTaps),
+  mTapsRegistered(0),
+  mTouchPosition(),
+  mTouchTime(0u),
+  mLastTapTime(0u)
+{
+}
+
+TapGestureRecognizer::~TapGestureRecognizer()
+{
+}
+
+void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
+{
+  if (event.GetPointCount() == 1)
+  {
+    const Integration::Point& point = event.points[0];
+    PointState::Type pointState = point.GetState();
+
+    switch (mState)
+    {
+      case Clear:
+      {
+        if (pointState == PointState::DOWN)
+        {
+          SetupForTouchDown( event, point );
+        }
+        break;
+      }
+
+      case Touched:
+      {
+        uint32_t deltaBetweenTouchDownTouchUp = event.time - mTouchTime;
+
+        if ( pointState == PointState::UP )
+        {
+          if ( deltaBetweenTouchDownTouchUp < MAXIMUM_TIME_ALLOWED )
+          {
+            mLastTapTime = mTouchTime;
+            EmitSingleTap( event.time, point );
+            mState = Registered;
+          }
+          else
+          {
+            mState = Clear;
+          }
+        }
+        else if (pointState == PointState::INTERRUPTED)
+        {
+          mState = Clear;
+        }
+        break;
+      }
+
+      case Registered:
+      {
+        if ( pointState == PointState::UP )
+        {
+          uint32_t deltaBetweenTouchDownTouchUp = event.time - mTouchTime;
+
+          if ( deltaBetweenTouchDownTouchUp < MAXIMUM_TIME_ALLOWED )
+          {
+            // This is a possible multiple tap, so has it been quick enough?
+            uint32_t timeDelta = event.time - mLastTapTime;
+            if( timeDelta > MAXIMUM_TIME_ALLOWED ) // If exceeded time between taps then just a single tap
+            {
+              mLastTapTime = event.time;
+              EmitSingleTap(event.time, point);
+              mState = Registered;
+            }
+            else
+            {
+              ++mTapsRegistered;
+              EmitGesture( Gesture::Started, event.time );
+              mState = Clear;
+            }
+          }
+          else // Delta between touch down and touch up too long to be considered a Tap event
+          {
+            mState = Clear;
+          }
+        }
+        else if (pointState == PointState::DOWN)
+        {
+          const Vector2& screen( point.GetScreenPosition() );
+          Vector2 distanceDelta(abs(mTouchPosition.x - screen.x),
+                                abs(mTouchPosition.y - screen.y));
+
+          uint32_t timeDelta = event.time - mLastTapTime;
+
+          if (distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
+              distanceDelta.y > MAXIMUM_MOTION_ALLOWED ||
+              timeDelta > MAXIMUM_TIME_ALLOWED )
+          {
+            SetupForTouchDown( event, point );
+          }
+          else
+          {
+            EmitPossibleState( event );
+          }
+        }
+        break;
+      }
+
+      case Failed:
+      default:
+      {
+        mState = Clear;
+        break;
+      }
+    }
+  }
+  else
+  {
+    mState = Failed;
+
+    // We have entered a multi-touch event so emit registered gestures if required.
+    EmitGesture(Gesture::Started, event.time);
+  }
+}
+
+void TapGestureRecognizer::SetupForTouchDown( const Integration::TouchEvent& event, const Integration::Point& point )
+{
+  mTouchPosition = point.GetScreenPosition();
+  mTouchTime = event.time;
+  mLastTapTime = 0u;
+  mTapsRegistered = 0;
+  mState = Touched;
+  EmitPossibleState( event );
+}
+
+void TapGestureRecognizer::EmitPossibleState( const Integration::TouchEvent& event )
+{
+  TapGestureEvent tapEvent( Gesture::Possible );
+  tapEvent.point = mTouchPosition;
+  tapEvent.time = event.time;
+
+  ProcessEvent( tapEvent );
+}
+
+
+void TapGestureRecognizer::Update(const GestureRequest& request)
+{
+  const TapGestureRequest& tap = static_cast<const TapGestureRequest&>(request);
+
+  mMinimumTapsRequired = tap.minTaps;
+  mMaximumTapsRequired = tap.maxTaps;
+}
+
+void TapGestureRecognizer::EmitGesture( Gesture::State state, uint32_t time )
+{
+  if ( (state == Gesture::Cancelled) ||
+       (mTapsRegistered >= mMinimumTapsRequired && mTapsRegistered <= mMaximumTapsRequired) )
+
+  {
+    TapGestureEvent event( state );
+    EmitTap( time, event );
+  }
+}
+
+void TapGestureRecognizer::EmitSingleTap( uint32_t time, const Integration::Point& point )
+{
+  TapGestureEvent event( Gesture::Started );
+  const Vector2& screen( point.GetScreenPosition() );
+  Vector2 distanceDelta(abs(mTouchPosition.x - screen.x),
+                        abs(mTouchPosition.y - screen.y));
+
+  if (distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
+      distanceDelta.y > MAXIMUM_MOTION_ALLOWED )
+  {
+    event.state = Gesture::Cancelled;
+  }
+  mTapsRegistered = 1u;
+  EmitTap( time, event );
+}
+
+void TapGestureRecognizer::EmitTap( uint32_t time, TapGestureEvent& event )
+{
+  event.numberOfTaps = mTapsRegistered;
+  event.point = mTouchPosition;
+  event.time = time;
+
+  ProcessEvent( event );
+}
+
+void TapGestureRecognizer::ProcessEvent( TapGestureEvent& event )
+{
+  if( mScene )
+  {
+    // Create another handle so the recognizer cannot be destroyed during process function
+    GestureRecognizerPtr recognizerHandle = this;
+    mObserver.Process(*mScene, event);
+  }
+}
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/dali/internal/event/events/tap-gesture-recognizer.h b/dali/internal/event/events/tap-gesture-recognizer.h
new file mode 100644 (file)
index 0000000..0c6012f
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef DALI_INTERNAL_EVENT_EVENTS_TAP_GESTURE_RECOGNIZER_H
+#define DALI_INTERNAL_EVENT_EVENTS_TAP_GESTURE_RECOGNIZER_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <cstdint>
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/integration-api/events/point.h>
+
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/events/gesture-recognizer.h>
+#include <dali/internal/event/events/tap-gesture-event.h>
+
+namespace Dali
+{
+
+namespace Integration
+{
+struct TouchEvent;
+}
+
+namespace Internal
+{
+struct TapGestureRequest;
+
+/**
+ * When given a set of touch events, this detector attempts to determine if a tap gesture has taken place.
+ */
+class TapGestureRecognizer : public GestureRecognizer
+{
+public:
+
+  using Observer = RecognizerObserver<TapGestureEvent>;
+
+  /**
+   * Constructor
+   * @param[in] coreEventInterface Used to send events to Core.
+   * @param[in]  screenSize  The size of the screen.
+   * @param[in]  request     The tap gesture request.
+   */
+  TapGestureRecognizer(Observer& observer, Vector2 screenSize, const TapGestureRequest& request);
+
+  /**
+   * Virtual destructor.
+   */
+  virtual ~TapGestureRecognizer();
+
+public:
+
+  /**
+   * @copydoc Dali::Internal::GestureDetector::SendEvent(const Integration::TouchEvent&)
+   */
+  virtual void SendEvent(const Integration::TouchEvent& event);
+
+  /**
+   * @copydoc Dali::Internal::GestureDetector::Update(const Integration::GestureRequest&)
+   */
+  virtual void Update(const GestureRequest& request);
+
+private:
+
+  /**
+   * Checks if registered taps are within required bounds and emits tap gesture if they are.
+   *
+   * @param[in] state current state of incomplete gesture
+   * @param[in] time time of this latest touch event
+   */
+  void EmitGesture( Gesture::State state, uint32_t time );
+
+  /**
+   * Initialises tap gesture detector for next tap sequence
+   *
+   * @param[in] event registered touch event
+   * @param[in] point position touch event occurred
+   */
+  void SetupForTouchDown( const Integration::TouchEvent& event, const Integration::Point& point );
+
+  /**
+   * Emit a touch down event for hit testing
+   *
+   * @param[in] event registered touch event
+   */
+  void EmitPossibleState( const Integration::TouchEvent& event );
+
+  /**
+   * Force a touch event sequence to be treated as a single tap
+   *
+   * @param[in] time time of this latest touch event
+   * @param[in] point position touch event occurred
+    */
+  void EmitSingleTap( uint32_t time, const Integration::Point& point );
+
+  /**
+   * Emit a tap event
+   *
+   * @param[in] time time of this latest touch event
+   * @param[in] event registered touch event
+   */
+  void EmitTap( uint32_t time, TapGestureEvent& event );
+
+  /**
+   * Send the event for processing
+   *
+   * @param[in] tap event for processing
+   */
+  void ProcessEvent( TapGestureEvent& event );
+
+private:
+
+  // Reference to the gesture processor for this recognizer
+  Observer& mObserver;
+
+  /**
+   * Internal state machine.
+   */
+  enum State
+  {
+    Clear,      ///< No gesture detected.
+    Touched,    ///< User is touching the screen.
+    Registered, ///< At least one tap has been registered.
+    Failed,     ///< Gesture has failed.
+  };
+
+  State mState; ///< Current state of the detector.
+
+  int mMinimumTapsRequired; ///< Minimum number of taps required.
+  int mMaximumTapsRequired; ///< Maximum number of taps required.
+  int mTapsRegistered;      ///< In current detection, the number of taps registered.
+
+  Vector2 mTouchPosition;   ///< The initial touch down position.
+  uint32_t mTouchTime; ///< The initial touch down time.
+  uint32_t mLastTapTime; ///< Time last tap gesture was registered
+
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+
+#endif // DALI_INTERNAL_EVENT_EVENTS_TAP_GESTURE_RECOGNIZER_H
index c007a04..bd5f8ce 100644 (file)
@@ -48,20 +48,29 @@ internal_src_files = \
   $(internal_src_dir)/event/events/key-event-impl.cpp \
   $(internal_src_dir)/event/events/key-event-processor.cpp \
   $(internal_src_dir)/event/events/gesture-detector-impl.cpp \
+  $(internal_src_dir)/event/events/gesture-event.cpp \
   $(internal_src_dir)/event/events/gesture-event-processor.cpp \
   $(internal_src_dir)/event/events/gesture-processor.cpp \
   $(internal_src_dir)/event/events/hit-test-algorithm-impl.cpp \
   $(internal_src_dir)/event/events/hover-event-processor.cpp \
   $(internal_src_dir)/event/events/long-press-gesture-detector-impl.cpp \
+  $(internal_src_dir)/event/events/long-press-gesture-event.cpp \
   $(internal_src_dir)/event/events/long-press-gesture-processor.cpp \
+  $(internal_src_dir)/event/events/long-press-gesture-recognizer.cpp \
   $(internal_src_dir)/event/events/wheel-event-processor.cpp \
   $(internal_src_dir)/event/events/multi-point-event-util.cpp \
   $(internal_src_dir)/event/events/pan-gesture-detector-impl.cpp \
+  $(internal_src_dir)/event/events/pan-gesture-event.cpp \
   $(internal_src_dir)/event/events/pan-gesture-processor.cpp \
+  $(internal_src_dir)/event/events/pan-gesture-recognizer.cpp \
   $(internal_src_dir)/event/events/pinch-gesture-detector-impl.cpp \
+  $(internal_src_dir)/event/events/pinch-gesture-event.cpp \
   $(internal_src_dir)/event/events/pinch-gesture-processor.cpp \
+  $(internal_src_dir)/event/events/pinch-gesture-recognizer.cpp \
   $(internal_src_dir)/event/events/tap-gesture-detector-impl.cpp \
+  $(internal_src_dir)/event/events/tap-gesture-event.cpp \
   $(internal_src_dir)/event/events/tap-gesture-processor.cpp \
+  $(internal_src_dir)/event/events/tap-gesture-recognizer.cpp \
   $(internal_src_dir)/event/events/touch-data-impl.cpp \
   $(internal_src_dir)/event/events/touch-event-processor.cpp \
   $(internal_src_dir)/event/images/bitmap-packed-pixel.cpp \
index 0d2b829..274b0ec 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TAP_GESTURE_DETECTOR_H__
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -150,7 +150,7 @@ public: // Setters
    * @SINCE_1_0.0
    * @param[in] minimumTaps The minimum taps required
    * @pre The gesture detector has been initialized.
-   * @note The default is '1'.
+   * @note The default is '1', the maximum is 2.
    */
   void SetMinimumTapsRequired( uint32_t minimumTaps );
 
@@ -161,7 +161,7 @@ public: // Setters
    * @SINCE_1_0.0
    * @param[in] maximumTaps The maximum taps required
    * @pre The gesture detector has been initialized.
-   * @note The default is '1'.
+   * @note The default is '1', the maximum is 2.
    */
   void SetMaximumTapsRequired( uint32_t maximumTaps );