#include <iostream>
#include <stdlib.h>
-#include <dali/dali.h>
+#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/system-overlay.h>
#include <dali/integration-api/profiling.h>
+#include <dali/integration-api/input-options.h>
#include <dali-test-suite-utils.h>
#include <test-touch-utils.h>
{
typedef Dali::PanGestureDetector::AngleContainer::size_type AngleSizeType;
+const int PAN_EVENT_TIME_DELTA = 8;
+const int PAN_GESTURE_UPDATE_COUNT = 50;
// Stores data that is populated in the callback and will be read by the test cases
struct SignalData
receivedGesture.screenPosition = Vector2(0.0f, 0.0f);
receivedGesture.numberOfTouches = 0;
- pannedActor = NULL;
+ pannedActor.Reset();
}
bool functorCalled;
{
GestureReceivedFunctor(SignalData& data) : signalData(data) { }
- void operator()(Actor actor, PanGesture pan)
+ void operator()(Actor actor, const PanGesture& pan)
{
signalData.functorCalled = true;
signalData.receivedGesture = pan;
{
}
- void operator()( Actor actor, PanGesture pan )
+ void operator()( Actor actor, const PanGesture& pan )
{
GestureReceivedFunctor::operator()( actor, pan );
Vector2 screenPosition;
Vector2 screenDisplacement;
+ Vector2 screenVelocity;
Vector2 localPosition;
Vector2 localDisplacement;
+ Vector2 localVelocity;
bool called;
void Reset()
{
- screenPosition = screenDisplacement = localPosition = localDisplacement = Vector2::ZERO;
+ screenPosition = screenDisplacement = screenVelocity = localPosition = localDisplacement = localVelocity = Vector2::ZERO;
called = false;
}
};
Vector3 operator()(const Vector3& current,
const PropertyInput& screenPositionProperty,
const PropertyInput& screenDisplacementProperty,
+ const PropertyInput& screenVelocityProperty,
const PropertyInput& localPositionProperty,
- const PropertyInput& localDisplacementProperty)
+ const PropertyInput& localDisplacementProperty,
+ const PropertyInput& localVelocityProperty)
{
constraintData.screenPosition = screenPositionProperty.GetVector2();
constraintData.screenDisplacement = screenDisplacementProperty.GetVector2();
+ constraintData.screenVelocity = screenVelocityProperty.GetVector2();
constraintData.localPosition = localPositionProperty.GetVector2();
constraintData.localDisplacement = localDisplacementProperty.GetVector2();
+ constraintData.localVelocity = localVelocityProperty.GetVector2();
constraintData.called = true;
return Vector3::ZERO;
}
Vector2 localPosition,
Vector2 screenDisplacement = Vector2::ONE,
Vector2 localDisplacement = Vector2::ONE,
- Vector2 velocity = Vector2::ONE,
+ Vector2 screenVelocity = Vector2::ONE,
+ Vector2 localVelocity = Vector2::ONE,
unsigned int numberOfTouches = 1 )
{
PanGesture pan( state );
pan.screenDisplacement = screenDisplacement;
pan.displacement = localDisplacement;
- pan.screenVelocity = pan.velocity = velocity;
+ pan.screenVelocity = screenVelocity;
+ pan.velocity = localVelocity;
+
pan.numberOfTouches = numberOfTouches;
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 start, Vector2 direction, int frames, bool finish = true)
+{
+ // Now do a pan starting from (start) and heading (direction)
+ Vector2 pos(start);
+ SendPan(application, Gesture::Possible, pos);
+ SendPan(application, Gesture::Started, pos);
+ application.SendNotification();
+ application.Render();
+
+ for(int i = 0;i<frames;i++)
+ {
+ pos += direction; // Move in this direction
+ SendPan(application, Gesture::Continuing, pos);
+ application.SendNotification();
+ application.Render();
+ }
+
+ if(finish)
+ {
+ SendPan(application, Gesture::Finished, pos);
+ application.SendNotification();
+ application.Render();
+ }
+
+ return pos;
+}
+
} // anon namespace
///////////////////////////////////////////////////////////////////////////////
application.Render();
// Delete actor as well
- actor = NULL;
+ actor.Reset();
// Render and notify
application.SendNotification();
END_TEST;
}
+int UtcDaliPanGestureNoPredictionNoSmoothing(void)
+{
+ TestApplication application;
+ Integration::SetPanGesturePredictionMode(0);
+ Integration::SetPanGestureSmoothingMode(0);
+
+ Actor actor = Actor::New();
+ actor.SetSize(100.0f, 100.0f);
+ actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ Stage::GetCurrent().Add(actor);
+
+ // Add a pan detector
+ PanGestureDetector detector = PanGestureDetector::New();
+ detector.Attach( actor );
+ SignalData data;
+ GestureReceivedFunctor functor( data );
+ detector.DetectedSignal().Connect( &application, functor );
+
+ Property::Index property = actor.RegisterProperty( "Dummy Property", Vector3::ZERO );
+
+ ConstraintData constraintData;
+ actor.ApplyConstraint( Constraint::New<Vector3>( property, Source( detector, PanGestureDetector::SCREEN_POSITION ),
+ Source( detector, PanGestureDetector::SCREEN_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::SCREEN_VELOCITY ),
+ Source( detector, PanGestureDetector::LOCAL_POSITION ),
+ Source( detector, PanGestureDetector::LOCAL_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::LOCAL_VELOCITY ),
+ PanConstraint( constraintData ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ Vector2 direction(Vector2::XAXIS * -5.0f);
+ Vector2 startPosition( 1.0f, 1.0f );
+ PerformSwipeGestureSwipe(application, startPosition, direction, PAN_GESTURE_UPDATE_COUNT, true);
+ 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 );
+ DALI_TEST_EQUALS( constraintData.localPosition, startPosition + (direction * PAN_GESTURE_UPDATE_COUNT), 0.1f, TEST_LOCATION );
+
+ constraintData.Reset();
+ END_TEST;
+}
+
+int UtcDaliPanGestureNoPredictionSmoothing(void)
+{
+ TestApplication application;
+ Integration::SetPanGesturePredictionMode(0);
+ Integration::SetPanGestureSmoothingMode(1);
+
+ Actor actor = Actor::New();
+ actor.SetSize(100.0f, 100.0f);
+ actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ Stage::GetCurrent().Add(actor);
+
+ // Add a pan detector
+ PanGestureDetector detector = PanGestureDetector::New();
+ detector.Attach( actor );
+ SignalData data;
+ GestureReceivedFunctor functor( data );
+ detector.DetectedSignal().Connect( &application, functor );
+
+ Property::Index property = actor.RegisterProperty( "Dummy Property", Vector3::ZERO );
+
+ ConstraintData constraintData;
+ actor.ApplyConstraint( Constraint::New<Vector3>( property, Source( detector, PanGestureDetector::SCREEN_POSITION ),
+ Source( detector, PanGestureDetector::SCREEN_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::SCREEN_VELOCITY ),
+ Source( detector, PanGestureDetector::LOCAL_POSITION ),
+ Source( detector, PanGestureDetector::LOCAL_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::LOCAL_VELOCITY ),
+ PanConstraint( constraintData ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ 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, true);
+ 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), 0.1f, TEST_LOCATION );
+ DALI_TEST_EQUALS( constraintData.localPosition, Vector2(1.0f, 1.0f) + (direction * PAN_GESTURE_UPDATE_COUNT), 0.1f, TEST_LOCATION );
+
+ constraintData.Reset();
+ END_TEST;
+}
+
+int UtcDaliPanGesturePredictionNoSmoothing(void)
+{
+ TestApplication application;
+ Integration::SetPanGesturePredictionMode(1);
+ Integration::SetPanGestureSmoothingMode(0);
+
+ Actor actor = Actor::New();
+ actor.SetSize(100.0f, 100.0f);
+ actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ Stage::GetCurrent().Add(actor);
+
+ // Add a pan detector
+ PanGestureDetector detector = PanGestureDetector::New();
+ detector.Attach( actor );
+ SignalData data;
+ GestureReceivedFunctor functor( data );
+ detector.DetectedSignal().Connect( &application, functor );
+
+ Property::Index property = actor.RegisterProperty( "Dummy Property", Vector3::ZERO );
+
+ ConstraintData constraintData;
+ actor.ApplyConstraint( Constraint::New<Vector3>( property, Source( detector, PanGestureDetector::SCREEN_POSITION ),
+ Source( detector, PanGestureDetector::SCREEN_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::SCREEN_VELOCITY ),
+ Source( detector, PanGestureDetector::LOCAL_POSITION ),
+ Source( detector, PanGestureDetector::LOCAL_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::LOCAL_VELOCITY ),
+ PanConstraint( constraintData ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ 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, true);
+ 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 );
+ DALI_TEST_EQUALS( constraintData.localPosition, Vector2(1.0f, 1.0f) + (direction * PAN_GESTURE_UPDATE_COUNT), 10.0f, TEST_LOCATION );
+
+ constraintData.Reset();
+ END_TEST;
+}
+
+int UtcDaliPanGesturePredictionSmoothing(void)
+{
+ TestApplication application;
+ Integration::SetPanGesturePredictionMode(1);
+ Integration::SetPanGestureSmoothingMode(1);
+
+ Actor actor = Actor::New();
+ actor.SetSize(100.0f, 100.0f);
+ actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ Stage::GetCurrent().Add(actor);
+
+ // Add a pan detector
+ PanGestureDetector detector = PanGestureDetector::New();
+ detector.Attach( actor );
+ SignalData data;
+ GestureReceivedFunctor functor( data );
+ detector.DetectedSignal().Connect( &application, functor );
+
+ Property::Index property = actor.RegisterProperty( "Dummy Property", Vector3::ZERO );
+
+ ConstraintData constraintData;
+ actor.ApplyConstraint( Constraint::New<Vector3>( property, Source( detector, PanGestureDetector::SCREEN_POSITION ),
+ Source( detector, PanGestureDetector::SCREEN_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::SCREEN_VELOCITY ),
+ Source( detector, PanGestureDetector::LOCAL_POSITION ),
+ Source( detector, PanGestureDetector::LOCAL_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::LOCAL_VELOCITY ),
+ PanConstraint( constraintData ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ 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, true);
+ 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 );
+ DALI_TEST_EQUALS( constraintData.localPosition, Vector2(1.0f, 1.0f) + (direction * PAN_GESTURE_UPDATE_COUNT), 10.0f, TEST_LOCATION );
+
+ constraintData.Reset();
+ END_TEST;
+}
+
int UtcDaliPanGestureSetProperties(void)
{
TestApplication application;
TestRenderController& renderController( application.GetRenderController() );
Integration::SetPanGesturePredictionMode(0);
+ Integration::SetPanGestureSmoothingMode(0);
Actor actor = Actor::New();
actor.SetSize(100.0f, 100.0f);
ConstraintData constraintData;
actor.ApplyConstraint( Constraint::New<Vector3>( property, Source( detector, PanGestureDetector::SCREEN_POSITION ),
Source( detector, PanGestureDetector::SCREEN_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::SCREEN_VELOCITY ),
Source( detector, PanGestureDetector::LOCAL_POSITION ),
Source( detector, PanGestureDetector::LOCAL_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::LOCAL_VELOCITY ),
PanConstraint( constraintData ) ) );
// Render and notify
Vector2 screenPosition( 20.0f, 20.0f );
Vector2 screenDisplacement( 1.0f, 1.0f );
+ Vector2 screenVelocity( 1.3f, 4.0f );
Vector2 localPosition( 21.0f, 21.0f );
Vector2 localDisplacement( 0.5f, 0.5f );
+ Vector2 localVelocity( 1.5f, 2.5f );
- PanGestureDetector::SetPanGestureProperties( GeneratePan( 1u, Gesture::Started, screenPosition, localPosition, screenDisplacement, localDisplacement ) );
+ PanGestureDetector::SetPanGestureProperties( GeneratePan( 1u, Gesture::Started, screenPosition, localPosition, screenDisplacement, localDisplacement, screenVelocity, localVelocity ) );
DALI_TEST_EQUALS( renderController.WasCalled( TestRenderController::RequestUpdateFunc ), true, TEST_LOCATION );
// Render and notify
DALI_TEST_EQUALS( constraintData.localPosition, localPosition, TEST_LOCATION );
DALI_TEST_EQUALS( constraintData.screenDisplacement, screenDisplacement, TEST_LOCATION );
DALI_TEST_EQUALS( constraintData.localDisplacement, localDisplacement, TEST_LOCATION );
+ DALI_TEST_EQUALS( constraintData.screenVelocity, screenVelocity, TEST_LOCATION );
+ DALI_TEST_EQUALS( constraintData.localVelocity, localVelocity, TEST_LOCATION );
constraintData.Reset();
END_TEST;
}
ConstraintData constraintData;
actor.ApplyConstraint( Constraint::New<Vector3>( property, Source( detector, PanGestureDetector::SCREEN_POSITION ),
Source( detector, PanGestureDetector::SCREEN_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::SCREEN_VELOCITY ),
Source( detector, PanGestureDetector::LOCAL_POSITION ),
Source( detector, PanGestureDetector::LOCAL_DISPLACEMENT ),
+ Source( detector, PanGestureDetector::LOCAL_VELOCITY ),
PanConstraint( constraintData ) ) );
// Render and notify
DALI_TEST_EQUALS( indices.size(), detector.GetPropertyCount(), TEST_LOCATION );
END_TEST;
}
+
+int UtcDaliPanGestureLayerConsumesTouch(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ actor.SetSize(100.0f, 100.0f);
+ actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ Stage::GetCurrent().Add(actor);
+
+ // Add a pan detector
+ PanGestureDetector detector = PanGestureDetector::New();
+ detector.Attach( actor );
+ SignalData data;
+ GestureReceivedFunctor functor( data );
+ detector.DetectedSignal().Connect( &application, functor );
+
+ // Add a layer to overlap the actor
+ Layer layer = Layer::New();
+ layer.SetSize(100.0f, 100.0f);
+ layer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ Stage::GetCurrent().Add( layer );
+ layer.RaiseToTop();
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Emit 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));
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Set layer to consume all touch
+ layer.SetTouchConsumed( true );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Emit the same signals again, should not receive
+ application.ProcessEvent(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));
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ END_TEST;
+}
+
+int UtcDaliPanGestureNoTimeDiff(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ actor.SetSize(100.0f, 100.0f);
+ actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ Stage::GetCurrent().Add(actor);
+
+ // Add a pan detector
+ PanGestureDetector detector = PanGestureDetector::New();
+ detector.Attach( actor );
+ SignalData data;
+ GestureReceivedFunctor functor( data );
+ detector.DetectedSignal().Connect( &application, functor );
+
+ // Render and notify
+ 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));
+ 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 ) );
+ DALI_TEST_CHECK( !std::isinf( data.receivedGesture.screenVelocity.x ) );
+ DALI_TEST_CHECK( !std::isinf( data.receivedGesture.screenVelocity.y ) );
+ data.Reset();
+
+ data.Reset();
+
+ END_TEST;
+}