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_TouchLongPressGestureDetector.cpp
19 * @brief This is the implementation file for %_TouchLongPressGestureDetector class
22 * This file contains the implementation of %_TouchLongPressGestureDetector class.
25 #include <Elementary.h>
26 #include <FBaseUtilMath.h>
27 #include <FBaseColIEnumeratorT.h>
28 #include <FUiITouchLongPressGestureEventListener.h>
29 #include "FUi_TouchLongPressGestureDetector.h"
30 #include "FUi_ITouchLongPressGestureEventListener.h"
31 #include "FUi_TouchManager.h"
32 #include "FUi_TouchLongPressGestureDetectorImpl.h"
33 #include "FUi_TouchGestureTimerManager.h"
35 using namespace Tizen::Base::Utility;
36 using namespace Tizen::Base::Collection;
37 using namespace Tizen::Graphics;
39 namespace Tizen { namespace Ui
41 const int DEFAULT_DURATION = 500;
42 const int DEFAULT_MOVE_ALLOWANCE = 10;
43 const int DEFAULT_TOUCH_COUNT = 1;
44 const int MAX_TOUCH_COUNT = 10;
46 class _TouchLongPressGestureDetector::_LongPressInfo
54 _TouchLongPressGestureDetector::_TouchLongPressGestureDetector(void)
55 : __duration(DEFAULT_DURATION)
56 , __moveAllowance(DEFAULT_MOVE_ALLOWANCE)
57 , __touchCount(DEFAULT_TOUCH_COUNT)
58 , __maxPointId(DEFAULT_TOUCH_COUNT-1)
59 , __pGestureTimerManager(null)
60 , __touchCanceled(false)
62 , __pLongPressInfoList(null)
64 result r = GetLastResult();
65 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, GetErrorMessage(r));
67 __pLongPressInfoList = new (std::nothrow) ArrayListT<_LongPressInfo*>;
68 SysTryReturnVoidResult(NID_UI, __pLongPressInfoList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
70 int __duration = static_cast<int>(elm_config_longpress_timeout_get() * 1000);
76 for(int i=0; i < MAX_TOUCH_COUNT; i++)
78 _LongPressInfo* pLongPressInfo = new (std::nothrow) _LongPressInfo;
79 SysTryCatch(NID_UI, pLongPressInfo, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
81 pLongPressInfo->__isPressed = false;
82 pLongPressInfo->__isInBounds = false;
83 pLongPressInfo->__touchCount = 0;
85 __pLongPressInfoList->Add(pLongPressInfo);
88 SetDetectorType(_TOUCH_GESTURE_DETECTOR_TYPE_LONG_PRESS);
92 if (__pLongPressInfoList)
94 RemoveLongPressInfoList();
95 delete __pLongPressInfoList;
96 __pLongPressInfoList = null;
100 _TouchLongPressGestureDetector::~_TouchLongPressGestureDetector(void)
102 RemoveLongPressInfoList();
103 __pLongPressInfoList->RemoveAll();
105 delete __pLongPressInfoList;
106 __pLongPressInfoList = null;
108 if (__pGestureTimerManager != null)
110 __pGestureTimerManager->CancelTimer();
112 delete __pGestureTimerManager;
113 __pGestureTimerManager = null;
115 __touchCanceled = false;
120 _TouchLongPressGestureDetector::RemoveLongPressInfoList(void)
122 IEnumeratorT<_LongPressInfo*>* pEnumerator = __pLongPressInfoList->GetEnumeratorN();
125 while(pEnumerator->MoveNext() == E_SUCCESS)
127 _LongPressInfo* pLongPressInfo = null;
128 pEnumerator->GetCurrent(pLongPressInfo);
133 delete pLongPressInfo;
140 _TouchLongPressGestureDetector::SetDuration(int duration)
142 SysTryReturnResult(NID_UI, duration > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
144 __duration = duration;
149 _TouchLongPressGestureDetector::GetDuration(void) const
155 _TouchLongPressGestureDetector::SetMoveAllowance(int allowance)
157 SysTryReturnResult(NID_UI, allowance > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
159 __moveAllowance = allowance;
164 _TouchLongPressGestureDetector::SetMoveAllowance(float allowance)
166 SysTryReturnResult(NID_UI, allowance > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
168 __moveAllowance = allowance;
173 _TouchLongPressGestureDetector::GetMoveAllowance(void) const
175 return __moveAllowance;
179 _TouchLongPressGestureDetector::GetMoveAllowanceF(void) const
181 return __moveAllowance;
185 _TouchLongPressGestureDetector::SetTouchCount(int count)
187 SysTryReturnResult(NID_UI, count > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
189 __touchCount = count;
190 __maxPointId = __touchCount-1;
192 if (__touchCount > DEFAULT_TOUCH_COUNT)
194 _Control* pControl = GetControl();
195 if (pControl && !pControl->IsMultiTouchEnabled())
197 pControl->SetMultiTouchEnabled(true);
205 _TouchLongPressGestureDetector::GetTouchCount(void) const
211 _TouchLongPressGestureDetector::EnableToDeleteTimer(bool deleteTimer)
213 __deleteTimer = deleteTimer;
217 _TouchLongPressGestureDetector::IsPressed(void)
219 bool allPressed = false;
220 for(int i=0; i<__touchCount; i++)
222 _LongPressInfo* pLongPressInfo = null;
223 __pLongPressInfoList->GetAt(i, pLongPressInfo);
226 if (pLongPressInfo->__isPressed && pLongPressInfo->__isInBounds
227 && (pLongPressInfo->__touchCount == DEFAULT_TOUCH_COUNT))
242 _TouchLongPressGestureDetector::ResetGestureTimerManager(void)
244 if (__pGestureTimerManager)
246 delete __pGestureTimerManager;
247 __pGestureTimerManager = null;
249 __touchCanceled = false;
250 __deleteTimer = true;
254 _TouchLongPressGestureDetector::IsTouchCanceled(void) const
256 return __touchCanceled;
260 _TouchLongPressGestureDetector::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
262 if (touchinfo.GetPointId() > __maxPointId || GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY )
267 _LongPressInfo* pLongPressInfo = null;
268 __pLongPressInfoList->GetAt(touchinfo.GetPointId(), pLongPressInfo);
269 SysTryReturn(NID_UI, pLongPressInfo, false, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
271 pLongPressInfo->__isPressed = true;
272 pLongPressInfo->__isInBounds = true;
273 pLongPressInfo->__touchCount++;
274 SysTryReturn(NID_UI, __pLongPressInfoList->SetAt(pLongPressInfo, touchinfo.GetPointId()) == E_SUCCESS,
275 false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
277 bool allTouched = false;
278 for(int i=0; i<__touchCount; i++)
280 _LongPressInfo* pLongPressInfo = null;
281 __pLongPressInfoList->GetAt(i, pLongPressInfo);
284 if (pLongPressInfo->__isPressed)
297 SetGestureStart(true);
299 __pGestureTimerManager = new (std::nothrow) _TouchGestureTimerManager(*this);
300 SysTryReturn(NID_UI, __pGestureTimerManager, null, E_SYSTEM, "[E_SYSTEM] System error occurred.");
302 if (__pGestureTimerManager->IsTimerStarted() == false)
304 _Control* pControl = GetControl();
310 if (__pGestureTimerManager->StartTimer(__duration) != E_SUCCESS)
312 SysLogException(NID_UI, E_SYSTEM, "[E_SYSTEM] LongPress timer is not started.");
321 _TouchLongPressGestureDetector::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
323 if (touchinfo.GetPointId() > __maxPointId || GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY )
328 _LongPressInfo* pLongPressInfo = null;
329 __pLongPressInfoList->GetAt(touchinfo.GetPointId(), pLongPressInfo);
330 SysTryReturn(NID_UI, pLongPressInfo, false, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
332 if (!pLongPressInfo->__isInBounds)
337 _TouchManager* pTouchManager = _TouchManager::GetInstance();
338 SysTryReturn(NID_UI, pTouchManager, false, E_SYSTEM, "[E_SYSTEM] _TouchManager does not exist.");
340 Point startPoint(pTouchManager->GetStartPoint(touchinfo.GetPointId()).x, pTouchManager->GetStartPoint(touchinfo.GetPointId()).y);
341 _Control* pControl = GetControl();
344 startPoint.x -= pControl->GetAbsoluteBounds().x;
345 startPoint.y -= pControl->GetAbsoluteBounds().y;
348 if (Math::Abs(startPoint.x- touchinfo.GetCurrentPosition().x) > __moveAllowance
349 || Math::Abs(startPoint.y - touchinfo.GetCurrentPosition().y) > __moveAllowance)
351 pLongPressInfo->__isInBounds = false;
355 pLongPressInfo->__isInBounds = true;
358 SysTryReturn(NID_UI, __pLongPressInfoList->SetAt(pLongPressInfo, touchinfo.GetPointId()) == E_SUCCESS,
359 false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
365 _TouchLongPressGestureDetector::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
367 if (touchinfo.GetPointId() > __maxPointId || GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY )
372 _LongPressInfo* pLongPressInfo = null;
373 __pLongPressInfoList->GetAt(touchinfo.GetPointId(), pLongPressInfo);
374 SysTryReturn(NID_UI, pLongPressInfo, false, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
376 pLongPressInfo->__isPressed = false;
377 pLongPressInfo->__isInBounds = false;
379 SysTryReturn(NID_UI, __pLongPressInfoList->SetAt(pLongPressInfo, touchinfo.GetPointId()) == E_SUCCESS,
380 false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
382 //when touch is released not expired timer -> failed
383 if (IsGestureStarted() && __pGestureTimerManager != null && !__pGestureTimerManager->IsTimerExpired())
385 __pGestureTimerManager->CancelTimer();
387 delete __pGestureTimerManager;
388 __pGestureTimerManager = null;
390 SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_FAILED);
391 ClearLongPressInfoList();
398 _TouchLongPressGestureDetector::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
400 ClearLongPressInfoList();
402 if (__pGestureTimerManager != null && __pGestureTimerManager->IsTimerExpired() == false)
404 __pGestureTimerManager->CancelTimer();
405 __touchCanceled = true;
409 delete __pGestureTimerManager;
410 __pGestureTimerManager = null;
414 __touchCanceled = true;
422 _TouchLongPressGestureDetector::ClearLongPressInfoList(void)
424 for(int i=0; i < MAX_TOUCH_COUNT; i++)
426 _LongPressInfo* pLongPressInfo = null;
427 __pLongPressInfoList->GetAt(i, pLongPressInfo);
433 pLongPressInfo->__isPressed = false;
434 pLongPressInfo->__touchCount = 0;
435 pLongPressInfo->__isInBounds = false;
437 __pLongPressInfoList->SetAt(pLongPressInfo, i);