2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0/
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 * @file FUi_TouchTapGestureDetector.cpp
19 * @brief This is the implementation file for %_TouchTapGestureDetector class
22 * This file contains the implementation of %_TouchTapGestureDetector class.
25 #include <FBaseUtilMath.h>
26 #include <FBaseColIEnumeratorT.h>
27 #include <FBaseColIListT.h>
28 #include <FUiITouchTapGestureEventListener.h>
29 #include "FUi_TouchTapGestureDetector.h"
30 #include "FUi_TouchManager.h"
31 #include "FUi_ITouchTapGestureEventListener.h"
32 #include "FUi_TouchTapGestureDetectorImpl.h"
33 #include "FUi_FingerInfo.h"
34 #include "FUi_TouchGestureTimerManager.h"
36 using namespace Tizen::Graphics;
37 using namespace Tizen::Base::Utility;
38 using namespace Tizen::Base::Collection;
42 const int DEFAULT_INTERNAL = 330;
43 const int DEFAULT_TAP_COUNT = 2;
44 const int DEFAULT_MOVE_ALLOWANCE = 10;
45 const int DEFAULT_TOUCH_COUNT = 1;
46 const int MAX_TOUCH_COUNT = 10;
47 const int INIT_TAP_COUNT = 1;
48 const int INVALID_POINT_ID = 9999;
51 namespace Tizen { namespace Ui
54 class _TouchTapGestureDetector::_TapInfo
61 _TouchTapGestureDetector::_TouchTapGestureDetector(void)
62 : __tapCount(DEFAULT_TAP_COUNT)
63 , __interval(DEFAULT_INTERNAL)
64 , __touchCount(DEFAULT_TOUCH_COUNT)
65 , __oneTapMoveAllowance(DEFAULT_MOVE_ALLOWANCE)
66 , __oneTapIsInBounds(true)
67 , __maxPointId(DEFAULT_TOUCH_COUNT-1)
68 , __oneTapStartPoint(0, 0)
69 , __pGestureTimerManager(null)
70 , __pTapInfoList(null)
72 result r = GetLastResult();
73 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, GetErrorMessage(r));
75 __pGestureTimerManager = new (std::nothrow) _TouchGestureTimerManager(*this);
76 SysTryReturnVoidResult(NID_UI, __pGestureTimerManager, E_SYSTEM, "[E_SYSTEM] System error occurred..");
78 __pTapInfoList = new (std::nothrow) ArrayListT<_TapInfo*>;
79 SysTryReturnVoidResult(NID_UI, __pTapInfoList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
81 for(int i=0; i < MAX_TOUCH_COUNT; i++)
83 _TapInfo* pTapInfo = new (std::nothrow) _TapInfo;
84 SysTryCatch(NID_UI, pTapInfo, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
86 pTapInfo->__isPressed = false;
87 pTapInfo->__tappedCount = 0;
89 __pTapInfoList->Add(pTapInfo);
92 SetDetectorType(_TOUCH_GESTURE_DETECTOR_TYPE_TAP);
96 if (__pGestureTimerManager)
98 delete __pGestureTimerManager;
99 __pGestureTimerManager = null;
105 delete __pTapInfoList;
106 __pTapInfoList = null;
110 _TouchTapGestureDetector::~_TouchTapGestureDetector(void)
113 __pTapInfoList->RemoveAll();
115 delete __pTapInfoList;
116 __pTapInfoList = null;
118 delete __pGestureTimerManager;
119 __pGestureTimerManager = null;
123 _TouchTapGestureDetector::RemoveTapInfoList(void)
125 IEnumeratorT<_TapInfo*>* pEnumerator = __pTapInfoList->GetEnumeratorN();
128 while(pEnumerator->MoveNext() == E_SUCCESS)
130 _TapInfo* pTapInfo = null;
131 pEnumerator->GetCurrent(pTapInfo);
143 _TouchTapGestureDetector::SetTapCount(int count)
145 SysTryReturnResult(NID_UI, count > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
152 _TouchTapGestureDetector::GetTapCount(void) const
158 _TouchTapGestureDetector::SetTapInterval(long intarval)
160 SysTryReturnResult(NID_UI, intarval > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
162 __interval = intarval;
167 _TouchTapGestureDetector::GetTapInterval(void) const
173 _TouchTapGestureDetector::SetTouchCount(int count)
175 SysTryReturnResult(NID_UI, count > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
177 __touchCount = count;
178 __maxPointId = __touchCount - 1;
180 if (__touchCount > DEFAULT_TOUCH_COUNT)
182 _Control* pControl = GetControl();
183 if (pControl && !pControl->IsMultiTouchEnabled())
185 pControl->SetMultiTouchEnabled(true);
192 _TouchTapGestureDetector::GetTouchCount(void) const
198 _TouchTapGestureDetector::SetMoveAllowance(int allowance)
200 SysTryReturnResult(NID_UI, allowance >= 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
201 SysTryReturnResult(NID_UI, __touchCount == DEFAULT_TOUCH_COUNT, E_INVALID_CONDITION, "[E_INVALID_CONDITION] move allowance applies only for default(1) touch count.");
203 __oneTapMoveAllowance = allowance;
209 _TouchTapGestureDetector::GetMoveAllowance(void) const
211 return __oneTapMoveAllowance;
215 _TouchTapGestureDetector::SetMoveAllowance(float allowance)
217 SysTryReturnResult(NID_UI, allowance >= 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
218 SysTryReturnResult(NID_UI, __touchCount == DEFAULT_TOUCH_COUNT, E_INVALID_CONDITION, "[E_INVALID_CONDITION] move allowance applies only for default(1) touch count.");
220 __oneTapMoveAllowance = allowance;
226 _TouchTapGestureDetector::GetMoveAllowanceF(void) const
228 return __oneTapMoveAllowance;
232 _TouchTapGestureDetector::IsInBounds(void)
234 return __oneTapIsInBounds;
238 _TouchTapGestureDetector::IsAllTapped(void)
240 bool allTapped = true;
242 for(int i=0; i<__touchCount; i++)
244 _TapInfo* pTapInfo = null;
245 __pTapInfoList->GetAt(i, pTapInfo);
251 if (pTapInfo->__isPressed && pTapInfo->__tappedCount >= __tapCount)
265 _TouchTapGestureDetector::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
267 if (touchinfo.GetPointId() > __maxPointId || GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY)
272 _TapInfo* pTapInfo = null;
273 __pTapInfoList->GetAt(touchinfo.GetPointId(), pTapInfo);
274 SysTryReturn(NID_UI, pTapInfo, false, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
276 if (__touchCount == DEFAULT_TOUCH_COUNT)
278 if (pTapInfo->__tappedCount == 0)
280 __oneTapStartPoint.x = touchinfo.GetCurrentPosition().x;
281 __oneTapStartPoint.y = touchinfo.GetCurrentPosition().y;
284 if (Math::Abs(touchinfo.GetCurrentPosition().x - __oneTapStartPoint.x) > __oneTapMoveAllowance
285 || Math::Abs(touchinfo.GetCurrentPosition().y - __oneTapStartPoint.y) > __oneTapMoveAllowance)
287 __oneTapIsInBounds = false;
291 __oneTapIsInBounds = true;
296 __oneTapIsInBounds = true;
299 pTapInfo->__isPressed = true;
301 SysTryReturn(NID_UI, __pTapInfoList->SetAt(pTapInfo, touchinfo.GetPointId()) == E_SUCCESS,
302 false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
304 bool allTouched = false;
306 for(int i=0; i<__touchCount; i++)
308 _TapInfo* pAllTapInfo = null;
309 __pTapInfoList->GetAt(i, pAllTapInfo);
312 if (pAllTapInfo->__isPressed)
323 if (allTouched && !IsGestureStarted())
325 SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_READY);
326 SetGestureStart(true);
328 if (__pGestureTimerManager->IsTimerStarted() == false)
330 _Control* pControl = GetControl();
336 if (__pGestureTimerManager->StartTimer(__interval) != E_SUCCESS)
338 SysLogException(NID_UI, E_SYSTEM, "[E_SYSTEM] Tapping timer is not started.");
347 _TouchTapGestureDetector::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
349 if ((touchinfo.GetPointId() > __maxPointId) || (GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY))
354 if (__touchCount == DEFAULT_TOUCH_COUNT)
356 if (Math::Abs(touchinfo.GetCurrentPosition().x - __oneTapStartPoint.x) > __oneTapMoveAllowance
357 || Math::Abs(touchinfo.GetCurrentPosition().y - __oneTapStartPoint.y) > __oneTapMoveAllowance)
359 __oneTapIsInBounds = false;
360 __pGestureTimerManager->CancelTimer();
361 SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_FAILED);
370 _TouchTapGestureDetector::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
372 if ((touchinfo.GetPointId() > __maxPointId) || (GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY))
377 _TapInfo* pTapInfo = null;
378 __pTapInfoList->GetAt(touchinfo.GetPointId(), pTapInfo);
379 SysTryReturn(NID_UI, pTapInfo, false, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
381 if (pTapInfo->__isPressed)
383 pTapInfo->__tappedCount++;
384 SysTryReturn(NID_UI, __pTapInfoList->SetAt(pTapInfo, touchinfo.GetPointId()) == E_SUCCESS,
385 false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
387 if (__touchCount == DEFAULT_TOUCH_COUNT)
389 if (Math::Abs(touchinfo.GetCurrentPosition().x - __oneTapStartPoint.x) > __oneTapMoveAllowance
390 || Math::Abs(touchinfo.GetCurrentPosition().y - __oneTapStartPoint.y) > __oneTapMoveAllowance)
392 __oneTapIsInBounds = false;
397 if (IsGestureStarted() && !__pGestureTimerManager->IsTimerExpired())
399 if (IsAllTapped() && IsInBounds())
401 __pGestureTimerManager->CancelTimer();
402 SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_SUCCESS);
408 if (!IsAllTapped() && !IsGestureStarted())
410 if (!__pGestureTimerManager->IsTimerExpired())
412 __pGestureTimerManager->CancelTimer();
414 SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_FAILED);
423 _TouchTapGestureDetector::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
427 if (__pGestureTimerManager->IsTimerExpired() == false)
429 __pGestureTimerManager->CancelTimer();
436 _TouchTapGestureDetector::ClearTapInfoList(void)
438 for(int i=0; i < MAX_TOUCH_COUNT; i++)
440 _TapInfo* pTapInfo = null;
441 __pTapInfoList->GetAt(i, pTapInfo);
447 pTapInfo->__isPressed = false;
448 pTapInfo->__tappedCount = 0;
450 __pTapInfoList->SetAt(pTapInfo, i);