/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
// EXTERNAL INCLUDES
#include <cmath>
-#include <dali/public-api/events/touch-point.h>
+#include <dali/devel-api/events/touch-point.h>
#include <dali/public-api/math/vector2.h>
#include <dali/internal/event/events/pinch-gesture/pinch-gesture-event.h>
namespace
{
-const unsigned int MINIMUM_TOUCH_EVENTS_REQUIRED = 4;
-const unsigned int MINIMUM_TOUCH_EVENTS_REQUIRED_AFTER_START = 4;
-
const float MINIMUM_DISTANCE_IN_MILLIINCH = 45.0f; // This value is used for measuring minimum pinch distance in pixel.
const float MINIMUM_DISTANCE_IN_PIXEL = 10.0f; // This value is for devices that do not provide a valid dpi value. (assumes 220dpi)
} // unnamed namespace
-PinchGestureRecognizer::PinchGestureRecognizer( Observer& observer, Vector2 screenSize, Vector2 screenDpi, float minimumPinchDistance )
-: GestureRecognizer( screenSize, Gesture::Pinch ),
+PinchGestureRecognizer::PinchGestureRecognizer( Observer& observer, Vector2 screenSize, Vector2 screenDpi, float minimumPinchDistance, uint32_t minimumTouchEvents, uint32_t minimumTouchEventsAfterStart )
+: GestureRecognizer( screenSize, GestureType::PINCH ),
mObserver( observer ),
- mState( Clear ),
+ mState( CLEAR ),
mTouchEvents(),
mDefaultMinimumDistanceDelta( GetDefaultMinimumPinchDistance( screenDpi ) ),
- mStartingDistance( 0.0f )
+ mStartingDistance( 0.0f ),
+ mMinimumTouchEvents( minimumTouchEvents ),
+ mMinimumTouchEventsAfterStart( minimumTouchEventsAfterStart )
{
SetMinimumPinchDistance( minimumPinchDistance );
}
void PinchGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
{
int pointCount = event.GetPointCount();
+ GestureRecognizerPtr ptr(this); // To keep us from being destroyed during the life-time of this method
switch (mState)
{
- case Clear:
+ case CLEAR:
{
if (pointCount == 2)
{
// Change state to possible as we have two touch points.
- mState = Possible;
+ mState = POSSIBLE;
mTouchEvents.push_back(event);
}
break;
}
- case Possible:
+ case POSSIBLE:
{
if (pointCount != 2)
{
- // We no longer have two touch points so change state back to Clear.
- mState = Clear;
+ // 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)
+ if (currentPoint1.GetState() == PointState::UP || currentPoint2.GetState() == PointState::UP || currentPoint1.GetState() == PointState::INTERRUPTED)
{
- // One of our touch points has an Up event so change our state back to Clear.
- mState = Clear;
+ // 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)
+ if( mTouchEvents.size() >= mMinimumTouchEvents )
{
const Integration::Point& firstPoint1 = mTouchEvents[0].points[0];
const Integration::Point& firstPoint2 = mTouchEvents[0].points[1];
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);
+ mTouchEvents.erase( mTouchEvents.begin(), mTouchEvents.end() - mMinimumTouchEvents );
if ( !mTouchEvents.empty() )
{
mStartingDistance = GetDistance(mTouchEvents.begin()->points[0], mTouchEvents.begin()->points[1]);
// Send pinch started
- SendPinch(Gesture::Started, event);
+ SendPinch(GestureState::STARTED, event);
- mState = Started;
+ mState = STARTED;
}
mTouchEvents.clear();
}
- if (mState == Possible)
+ if (mState == POSSIBLE)
{
// No pinch, so restart detection
- mState = Clear;
+ mState = CLEAR;
mTouchEvents.clear();
}
}
break;
}
- case Started:
+ case STARTED:
{
- if (pointCount != 2)
+ if(event.points[0].GetState() == PointState::INTERRUPTED)
+ {
+ // System interruption occurred, pinch should be cancelled
+ mTouchEvents.clear();
+ SendPinch(GestureState::CANCELLED, event);
+ mState = CLEAR;
+ mTouchEvents.clear();
+ }
+ else if (pointCount != 2)
{
// Send pinch finished event
- SendPinch(Gesture::Finished, event);
+ SendPinch(GestureState::FINISHED, event);
- mState = Clear;
+ mState = CLEAR;
mTouchEvents.clear();
}
else
{
mTouchEvents.push_back(event);
// Send pinch finished event
- SendPinch(Gesture::Finished, event);
+ SendPinch(GestureState::FINISHED, event);
- mState = Clear;
+ mState = CLEAR;
mTouchEvents.clear();
}
else
{
mTouchEvents.push_back(event);
- if (mTouchEvents.size() >= MINIMUM_TOUCH_EVENTS_REQUIRED_AFTER_START)
+ if( mTouchEvents.size() >= mMinimumTouchEventsAfterStart )
{
// Send pinch continuing
- SendPinch(Gesture::Continuing, event);
+ SendPinch(GestureState::CONTINUING, event);
mTouchEvents.clear();
}
// Nothing to do.
}
-void PinchGestureRecognizer::SendPinch(Gesture::State state, const Integration::TouchEvent& currentEvent)
+void PinchGestureRecognizer::SendPinch(GestureState state, const Integration::TouchEvent& currentEvent)
{
PinchGestureEvent gesture(state);
else
{
// Something has gone wrong, just cancel the gesture.
- gesture.state = Gesture::Cancelled;
+ gesture.state = GestureState::CANCELLED;
}
gesture.time = currentEvent.time;
}
}
+void PinchGestureRecognizer::SetMinimumTouchEvents( uint32_t value )
+{
+ mMinimumTouchEvents = value;
+}
+
+void PinchGestureRecognizer::SetMinimumTouchEventsAfterStart( uint32_t value )
+{
+ mMinimumTouchEventsAfterStart = value;
+}
+
} // namespace Internal
} // namespace Dali