2 * Copyright (c) 2023 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 <dali/internal/event/events/tap-gesture/tap-gesture-recognizer.h>
24 #include <dali/public-api/math/vector2.h>
26 #include <dali/integration-api/events/touch-event-integ.h>
29 #include <dali/internal/event/common/scene-impl.h>
30 #include <dali/internal/event/events/gesture-requests.h>
37 TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSize, const TapGestureRequest& request, uint32_t maximumAllowedTime, uint32_t recognizerTime, float maximumMotionAllowedDistance)
38 : GestureRecognizer(screenSize, GestureType::TAP),
45 mDeltaBetweenTouchDownTouchUp(0u),
46 mMaximumAllowedTime(maximumAllowedTime),
47 mRecognizerTime(recognizerTime),
48 mMaximumMotionAllowedDistance(maximumMotionAllowedDistance)
52 TapGestureRecognizer::~TapGestureRecognizer() = default;
54 void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
56 GestureRecognizerPtr ptr(this); // To keep us from being destroyed during the life-time of this method
57 if(event.GetPointCount() == 1)
59 const Integration::Point& point = event.points[0];
60 PointState::Type pointState = point.GetState();
66 if(pointState == PointState::DOWN)
68 SetupForTouchDown(event, point);
75 if(pointState == PointState::UP)
77 mDeltaBetweenTouchDownTouchUp = event.time - mTouchTime;
78 if(mDeltaBetweenTouchDownTouchUp < mRecognizerTime)
80 EmitSingleTap(event.time, point);
83 else // Clear if the time between touch down and touch up is long.
86 DALI_LOG_RELEASE_INFO("time between touch down and touch up is long. (%dms > %dms)\n", mDeltaBetweenTouchDownTouchUp, mRecognizerTime);
89 else if(pointState == PointState::INTERRUPTED)
98 if(pointState == PointState::UP)
100 mDeltaBetweenTouchDownTouchUp = event.time - mTouchTime;
101 if(mDeltaBetweenTouchDownTouchUp < mRecognizerTime)
103 const Vector2& screen(point.GetScreenPosition());
104 Vector2 distanceDelta(std::abs(mTouchPosition.x - screen.x),
105 std::abs(mTouchPosition.y - screen.y));
106 if(distanceDelta.x > mMaximumMotionAllowedDistance ||
107 distanceDelta.y > mMaximumMotionAllowedDistance)
110 DALI_LOG_RELEASE_INFO("There is a long distance between touch down and touch up. (%f or %f > %f)\n", distanceDelta.x, distanceDelta.y, mMaximumMotionAllowedDistance);
114 EmitGesture(GestureState::STARTED, event.time);
117 else // Clear if the time between touch down and touch up is long.
120 DALI_LOG_RELEASE_INFO("time between touch down and touch up is long. (%dms > %dms)\n", mDeltaBetweenTouchDownTouchUp, mRecognizerTime);
123 else if(pointState == PointState::DOWN)
125 const Vector2& screen(point.GetScreenPosition());
126 Vector2 distanceDelta(std::abs(mTouchPosition.x - screen.x),
127 std::abs(mTouchPosition.y - screen.y));
129 uint32_t timeDelta = event.time - mLastTapTime;
130 mTouchTime = event.time;
132 if(distanceDelta.x > mMaximumMotionAllowedDistance ||
133 distanceDelta.y > mMaximumMotionAllowedDistance ||
134 timeDelta > mMaximumAllowedTime) // If the time between tabs is long, it starts over from SetupForTouchDown.
136 SetupForTouchDown(event, point);
140 EmitPossibleState(event);
160 void TapGestureRecognizer::SetupForTouchDown(const Integration::TouchEvent& event, const Integration::Point& point)
162 mTouchPosition = point.GetScreenPosition();
163 mTouchTime = event.time;
166 mTapsRegistered = 0u;
168 EmitPossibleState(event);
171 void TapGestureRecognizer::EmitPossibleState(const Integration::TouchEvent& event)
173 TapGestureEvent tapEvent(GestureState::POSSIBLE);
174 tapEvent.point = mTouchPosition;
175 tapEvent.time = event.time;
177 ProcessEvent(tapEvent);
180 void TapGestureRecognizer::Update(const GestureRequest& request)
185 void TapGestureRecognizer::SetMaximumAllowedTime(uint32_t time)
187 mMaximumAllowedTime = time;
190 void TapGestureRecognizer::SetRecognizerTime(uint32_t time)
192 mRecognizerTime = time;
195 void TapGestureRecognizer::SetMaximumMotionAllowedDistance(float distance)
197 mMaximumMotionAllowedDistance = distance;
200 void TapGestureRecognizer::EmitGesture(GestureState state, uint32_t time)
202 TapGestureEvent event(state);
203 EmitTap(time, event);
206 void TapGestureRecognizer::EmitSingleTap(uint32_t time, const Integration::Point& point)
208 TapGestureEvent event(GestureState::STARTED);
209 const Vector2& screen(point.GetScreenPosition());
210 Vector2 distanceDelta(std::abs(mTouchPosition.x - screen.x),
211 std::abs(mTouchPosition.y - screen.y));
213 if(distanceDelta.x > mMaximumMotionAllowedDistance ||
214 distanceDelta.y > mMaximumMotionAllowedDistance)
216 event.state = GestureState::CANCELLED;
217 DALI_LOG_RELEASE_INFO("There is a long distance between touch down and touch up. (%f or %f > %f)\n", distanceDelta.x, distanceDelta.y, mMaximumMotionAllowedDistance);
219 EmitTap(time, event);
222 void TapGestureRecognizer::EmitTap(uint32_t time, TapGestureEvent& event)
224 event.numberOfTaps = ++mTapsRegistered;
225 event.point = mTouchPosition;
227 mLastTapTime = event.time;
232 void TapGestureRecognizer::ProcessEvent(TapGestureEvent& event)
234 event.sourceType = mSourceType;
235 event.sourceData = mSourceData;
238 // Create another handle so the recognizer cannot be destroyed during process function
239 GestureRecognizerPtr recognizerHandle = this;
240 mObserver.Process(*mScene, event);
244 } // namespace Internal