2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 <FBaseUtilMath.h>
26 #include <FBaseColIEnumeratorT.h>
27 #include <FUiITouchLongPressGestureEventListener.h>
28 #include "FUi_TouchLongPressGestureDetector.h"
29 #include "FUi_ITouchLongPressGestureEventListener.h"
30 #include "FUi_TouchManager.h"
31 #include "FUi_TouchLongPressGestureDetectorImpl.h"
32 #include "FUi_TouchGestureTimerManager.h"
34 using namespace Tizen::Base::Utility;
35 using namespace Tizen::Base::Collection;
36 using namespace Tizen::Graphics;
38 namespace Tizen { namespace Ui
40 const int DEFAULT_DURATION = 500;
41 const int DEFAULT_MOVE_ALLOWANCE = 10;
42 const int DEFAULT_TOUCH_COUNT = 1;
43 const int MAX_TOUCH_COUNT = 10;
45 class _TouchLongPressGestureDetector::_LongPressInfo
53 _TouchLongPressGestureDetector::_TouchLongPressGestureDetector(void)
54 : __duration(DEFAULT_DURATION)
55 , __moveAllowance(DEFAULT_MOVE_ALLOWANCE)
56 , __touchCount(DEFAULT_TOUCH_COUNT)
57 , __maxPointId(DEFAULT_TOUCH_COUNT-1)
58 , __pGestureTimerManager(null)
59 , __pLongPressInfoList(null)
61 result r = GetLastResult();
62 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, GetErrorMessage(r));
64 __pLongPressInfoList = new (std::nothrow) ArrayListT<_LongPressInfo*>;
65 SysTryReturnVoidResult(NID_UI, __pLongPressInfoList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
67 for(int i=0; i < MAX_TOUCH_COUNT; i++)
69 _LongPressInfo* pLongPressInfo = new (std::nothrow) _LongPressInfo;
70 SysTryCatch(NID_UI, pLongPressInfo, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
72 pLongPressInfo->__isPressed = false;
73 pLongPressInfo->__isInBounds = false;
74 pLongPressInfo->__touchCount = 0;
76 __pLongPressInfoList->Add(pLongPressInfo);
79 SetDetectorType(_TOUCH_GESTURE_DETECTOR_TYPE_LONG_PRESS);
83 if (__pLongPressInfoList)
85 RemoveLongPressInfoList();
86 delete __pLongPressInfoList;
87 __pLongPressInfoList = null;
91 _TouchLongPressGestureDetector::~_TouchLongPressGestureDetector(void)
93 RemoveLongPressInfoList();
94 __pLongPressInfoList->RemoveAll();
96 delete __pLongPressInfoList;
97 __pLongPressInfoList = null;
99 if (__pGestureTimerManager != null)
101 __pGestureTimerManager->CancelTimer();
103 delete __pGestureTimerManager;
104 __pGestureTimerManager = null;
109 _TouchLongPressGestureDetector::RemoveLongPressInfoList(void)
111 IEnumeratorT<_LongPressInfo*>* pEnumerator = __pLongPressInfoList->GetEnumeratorN();
114 while(pEnumerator->MoveNext() == E_SUCCESS)
116 _LongPressInfo* pLongPressInfo = null;
117 pEnumerator->GetCurrent(pLongPressInfo);
122 delete pLongPressInfo;
129 _TouchLongPressGestureDetector::SetDuration(int duration)
131 SysTryReturnResult(NID_UI, duration > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
133 __duration = duration;
138 _TouchLongPressGestureDetector::GetDuration(void) const
144 _TouchLongPressGestureDetector::SetMoveAllowance(int allowance)
146 SysTryReturnResult(NID_UI, allowance > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
148 __moveAllowance = allowance;
153 _TouchLongPressGestureDetector::GetMoveAllowance(void) const
155 return __moveAllowance;
159 _TouchLongPressGestureDetector::SetTouchCount(int count)
161 SysTryReturnResult(NID_UI, count > 0, E_INVALID_ARG, "[E_INVALID_ARG] Argument is less than 0");
163 __touchCount = count;
164 __maxPointId = __touchCount-1;
166 if (__touchCount > DEFAULT_TOUCH_COUNT)
168 _Control* pControl = GetControl();
169 if (pControl && !pControl->IsMultiTouchEnabled())
171 pControl->SetMultiTouchEnabled(true);
179 _TouchLongPressGestureDetector::GetTouchCount(void) const
185 _TouchLongPressGestureDetector::IsPressed(void)
187 bool allPressed = false;
188 for(int i=0; i<__touchCount; i++)
190 _LongPressInfo* pLongPressInfo = null;
191 __pLongPressInfoList->GetAt(i, pLongPressInfo);
194 if (pLongPressInfo->__isPressed && pLongPressInfo->__isInBounds
195 && (pLongPressInfo->__touchCount == DEFAULT_TOUCH_COUNT))
210 _TouchLongPressGestureDetector::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
212 if (touchinfo.GetPointId() > __maxPointId || GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY )
217 _LongPressInfo* pLongPressInfo = null;
218 __pLongPressInfoList->GetAt(touchinfo.GetPointId(), pLongPressInfo);
219 SysTryReturn(NID_UI, pLongPressInfo, false, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
221 pLongPressInfo->__isPressed = true;
222 pLongPressInfo->__isInBounds = true;
223 pLongPressInfo->__touchCount++;
224 SysTryReturn(NID_UI, __pLongPressInfoList->SetAt(pLongPressInfo, touchinfo.GetPointId()) == E_SUCCESS,
225 false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
227 bool allTouched = false;
228 for(int i=0; i<__touchCount; i++)
230 _LongPressInfo* pLongPressInfo = null;
231 __pLongPressInfoList->GetAt(i, pLongPressInfo);
234 if (pLongPressInfo->__isPressed)
247 SetGestureStart(true);
249 __pGestureTimerManager = new (std::nothrow) _TouchGestureTimerManager(*this);
250 SysTryReturn(NID_UI, __pGestureTimerManager, null, E_SYSTEM, "[E_SYSTEM] System error occurred.");
252 if (__pGestureTimerManager->IsTimerStarted() == false)
254 _Control* pControl = GetControl();
260 if (__pGestureTimerManager->StartTimer(__duration) != E_SUCCESS)
262 SysLogException(NID_UI, E_SYSTEM, "[E_SYSTEM] LongPress timer is not started.");
271 _TouchLongPressGestureDetector::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
273 if (touchinfo.GetPointId() > __maxPointId || GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY )
278 _LongPressInfo* pLongPressInfo = null;
279 __pLongPressInfoList->GetAt(touchinfo.GetPointId(), pLongPressInfo);
280 SysTryReturn(NID_UI, pLongPressInfo, false, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
282 if (!pLongPressInfo->__isInBounds)
287 _TouchManager* pTouchManager = _TouchManager::GetInstance();
288 SysTryReturn(NID_UI, pTouchManager, false, E_SYSTEM, "[E_SYSTEM] _TouchManager does not exist.");
290 Point startPoint(pTouchManager->GetStartPoint(touchinfo.GetPointId()).x, pTouchManager->GetStartPoint(touchinfo.GetPointId()).y);
291 _Control* pControl = GetControl();
294 startPoint.x -= pControl->GetAbsoluteBounds().x;
295 startPoint.y -= pControl->GetAbsoluteBounds().y;
298 if (Math::Abs(startPoint.x- touchinfo.GetCurrentPosition().x) > __moveAllowance
299 || Math::Abs(startPoint.y - touchinfo.GetCurrentPosition().y) > __moveAllowance)
301 pLongPressInfo->__isInBounds = false;
305 pLongPressInfo->__isInBounds = true;
308 SysTryReturn(NID_UI, __pLongPressInfoList->SetAt(pLongPressInfo, touchinfo.GetPointId()) == E_SUCCESS,
309 false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
315 _TouchLongPressGestureDetector::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
317 if (touchinfo.GetPointId() > __maxPointId || GetDetectorState() != _TOUCH_GESTURE_DETECTOR_STATE_READY )
322 _LongPressInfo* pLongPressInfo = null;
323 __pLongPressInfoList->GetAt(touchinfo.GetPointId(), pLongPressInfo);
324 SysTryReturn(NID_UI, pLongPressInfo, false, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
326 pLongPressInfo->__isPressed = false;
327 pLongPressInfo->__isInBounds = false;
329 SysTryReturn(NID_UI, __pLongPressInfoList->SetAt(pLongPressInfo, touchinfo.GetPointId()) == E_SUCCESS,
330 false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
332 //when touch is released not expired timer -> failed
333 if (IsGestureStarted() && __pGestureTimerManager != null && !__pGestureTimerManager->IsTimerExpired())
335 __pGestureTimerManager->CancelTimer();
337 delete __pGestureTimerManager;
338 __pGestureTimerManager = null;
340 SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_FAILED);
341 ClearLongPressInfoList();
348 _TouchLongPressGestureDetector::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
350 ClearLongPressInfoList();
352 if (__pGestureTimerManager != null && __pGestureTimerManager->IsTimerExpired() == false)
354 __pGestureTimerManager->CancelTimer();
356 delete __pGestureTimerManager;
357 __pGestureTimerManager = null;
364 _TouchLongPressGestureDetector::ClearLongPressInfoList(void)
366 for(int i=0; i < MAX_TOUCH_COUNT; i++)
368 _LongPressInfo* pLongPressInfo = null;
369 __pLongPressInfoList->GetAt(i, pLongPressInfo);
375 pLongPressInfo->__isPressed = false;
376 pLongPressInfo->__touchCount = 0;
377 pLongPressInfo->__isInBounds = false;
379 __pLongPressInfoList->SetAt(pLongPressInfo, i);