2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "tap-gesture-detector.h"
24 #include <dali/public-api/math/vector2.h>
26 #include <dali/integration-api/events/gesture-requests.h>
27 #include <dali/integration-api/events/touch-event-integ.h>
28 #include <base/core-event-interface.h>
43 // TODO: Set these according to DPI
44 const float MAXIMUM_MOTION_ALLOWED = 20.0f;
45 const unsigned long MAXIMUM_TIME_ALLOWED = 500u;
46 } // unnamed namespace
48 TapGestureDetector::TapGestureDetector(CoreEventInterface& coreEventInterface, Vector2 screenSize, const Integration::TapGestureRequest& request)
49 : GestureDetector(screenSize, Gesture::Tap),
50 mCoreEventInterface(coreEventInterface),
52 mMinimumTapsRequired(request.minTaps),
53 mMaximumTapsRequired(request.maxTaps),
61 TapGestureDetector::~TapGestureDetector()
65 void TapGestureDetector::SendEvent(const Integration::TouchEvent& event)
67 if (event.GetPointCount() == 1)
69 const Integration::Point& point = event.points[0];
70 PointState::Type pointState = point.GetState();
76 if (pointState == PointState::DOWN)
78 SetupForTouchDown( event, point );
85 unsigned long deltaBetweenTouchDownTouchUp = abs( event.time - mTouchTime ) ;
87 if ( pointState == PointState::UP )
89 if ( deltaBetweenTouchDownTouchUp < MAXIMUM_TIME_ALLOWED )
91 mLastTapTime = mTouchTime;
92 EmitSingleTap( event.time, point );
100 else if (pointState == PointState::INTERRUPTED)
109 if ( pointState == PointState::UP )
111 unsigned long deltaBetweenTouchDownTouchUp = abs( event.time - mTouchTime ) ;
113 if ( deltaBetweenTouchDownTouchUp < MAXIMUM_TIME_ALLOWED )
115 // This is a possible multiple tap, so has it been quick enough ?
116 unsigned long timeDelta = abs( event.time - mLastTapTime );
117 if ( timeDelta > MAXIMUM_TIME_ALLOWED ) // If exceeded time between taps then just a single tap.
119 mLastTapTime = event.time;
120 EmitSingleTap( event.time, point );
126 EmitGesture( Gesture::Started, event.time );
130 else // Delta between touch down and touch up too long to be considered a Tap event
135 else if (pointState == PointState::DOWN)
137 const Vector2& screen( point.GetScreenPosition() );
138 Vector2 distanceDelta(abs(mTouchPosition.x - screen.x),
139 abs(mTouchPosition.y - screen.y));
141 unsigned long timeDelta = abs( event.time - mLastTapTime );
143 if (distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
144 distanceDelta.y > MAXIMUM_MOTION_ALLOWED ||
145 timeDelta > MAXIMUM_TIME_ALLOWED )
147 SetupForTouchDown( event, point );
151 EmitPossibleState( event );
169 // We have entered a multi-touch event so emit registered gestures if required.
170 EmitGesture(Gesture::Started, event.time);
174 void TapGestureDetector::SetupForTouchDown( const Integration::TouchEvent& event, const Integration::Point& point )
176 mTouchPosition = point.GetScreenPosition();
177 mTouchTime = event.time;
181 EmitPossibleState( event );
184 void TapGestureDetector::EmitPossibleState( const Integration::TouchEvent& event )
186 Integration::TapGestureEvent tapEvent( Gesture::Possible );
187 tapEvent.point = mTouchPosition;
188 tapEvent.time = event.time;
189 mCoreEventInterface.QueueCoreEvent(tapEvent);
193 void TapGestureDetector::Update(const Integration::GestureRequest& request)
195 const Integration::TapGestureRequest& tap = static_cast<const Integration::TapGestureRequest&>(request);
197 mMinimumTapsRequired = tap.minTaps;
198 mMaximumTapsRequired = tap.maxTaps;
201 void TapGestureDetector::EmitGesture( Gesture::State state, unsigned int time )
203 if ( (state == Gesture::Cancelled) ||
204 (mTapsRegistered >= mMinimumTapsRequired && mTapsRegistered <= mMaximumTapsRequired) )
207 Integration::TapGestureEvent event( state );
208 EmitTap( time, event );
212 void TapGestureDetector::EmitSingleTap( unsigned int time, const Integration::Point& point )
214 Integration::TapGestureEvent event( Gesture::Started );
215 const Vector2& screen( point.GetScreenPosition() );
216 Vector2 distanceDelta(abs(mTouchPosition.x - screen.x),
217 abs(mTouchPosition.y - screen.y));
219 if (distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
220 distanceDelta.y > MAXIMUM_MOTION_ALLOWED )
222 event.state = Gesture::Cancelled;
224 mTapsRegistered = 1u;
225 EmitTap( time, event );
228 void TapGestureDetector::EmitTap( unsigned int time, Integration::TapGestureEvent& event )
230 event.numberOfTaps = mTapsRegistered;
231 event.point = mTouchPosition;
233 mCoreEventInterface.QueueCoreEvent(event);
236 } // namespace Adaptor
238 } // namespace Internal