Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / FUi_TouchManager.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://floralicense.org/license/
10 //
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.
16 //
17
18 /**
19  * @file                        FUi_TouchManager.cpp
20  * @brief               This is the implementation file for _TouchManager class.
21  */
22
23 #include <math.h>
24 #include <FUiTouchGestureDetector.h>
25 #include <FBaseSysLog.h>
26 #include <pthread.h>
27 #include "FUi_UiTouchEvent.h"
28 #include "FUi_UiEventManager.h"
29 #include "FUi_ITouchEventListener.h"
30 #include "FUi_TouchGestureDetector.h"
31 #include "FUi_ControlManager.h"
32 #include "FUi_Control.h"
33 #include "FUi_TouchManager.h"
34 #include "FUi_ControlImpl.h"
35
36 using namespace Tizen::Base::Collection;
37 using namespace Tizen::Graphics;
38 using namespace Tizen::Ui;
39
40 namespace
41 {
42 class _TouchEventListener
43         : public _ITouchEventListener
44         , virtual public _IUiEventListener
45         , virtual public Tizen::Base::Runtime::IEventListener
46 {
47 public:
48         _TouchEventListener(void)
49         {
50         }
51
52         virtual ~_TouchEventListener(void)
53         {
54         }
55
56         virtual bool OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
57         {
58                 _TouchManager*  pTouchManager = _TouchManager::GetInstance();
59                 SysTryReturn(NID_UI, pTouchManager, false, E_SYSTEM, "[E_SYSTEM] _TouchManager does not exist.");
60
61                 if (touchinfo.GetPointId() == SINGLE_POINT_ID)
62                 {
63                         pTouchManager->SetTouchAllowed(true);
64                         pTouchManager->SetTouchCanceledOnGestureSuccess(false);
65                         pTouchManager->SetTouchControlSource(source);
66                         pTouchManager->SetFocusedControlSource(source);
67                 }
68                 else
69                 {
70                         _Control* pTouchedControl = pTouchManager->GetTouchControlSource();
71                         if (pTouchedControl == null)
72                         {
73                                 pTouchManager->SetTouchAllowed(true);
74                                 pTouchManager->SetTouchControlSource(source);
75                                 pTouchManager->SetFocusedControlSource(source);
76                         }
77                 }
78
79                 if (!pTouchManager->IsSendingDelayedEvent())
80                 {
81                         return false;
82                 }
83
84                 result r = pTouchManager->AddPoint(touchinfo.GetPointId(), touchinfo.GetCurrentPosition(), _TOUCH_PRESSED);
85                 SysTryReturn(NID_UI, r == E_SUCCESS, true, E_SYSTEM, "[E_SYSTEM] System error occurred.");
86
87                 return false;
88         }
89
90         virtual bool OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
91         {
92                 _TouchManager*  pTouchManager = _TouchManager::GetInstance();
93                 SysTryReturn(NID_UI, pTouchManager, false, E_SYSTEM, "[E_SYSTEM] _TouchManager does not exist.");
94
95                 if (!pTouchManager->IsTouchAllowed())
96                 {
97                         return true;
98                 }
99
100                 if (!pTouchManager->IsSendingDelayedEvent())
101                 {
102                         return false;
103                 }
104
105                 result r = pTouchManager->AddPoint(touchinfo.GetPointId(), touchinfo.GetCurrentPosition(), _TOUCH_RELEASED);
106                 SysTryReturn(NID_UI, r == E_SUCCESS, true, E_SYSTEM, "[E_SYSTEM] System error occurred.");
107
108                 return false;
109         }
110
111         virtual bool OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
112         {
113                 _TouchManager*  pTouchManager = _TouchManager::GetInstance();
114                 SysTryReturn(NID_UI, pTouchManager, false, E_SYSTEM, "[E_SYSTEM] _TouchManager does not exist.");
115
116                 if (!pTouchManager->IsTouchAllowed())
117                 {
118                         return true;
119                 }
120
121                 if(!pTouchManager->IsInTouchMoveAllowanceBounds(source, touchinfo))
122                 {
123                         return true;
124                 }
125
126                 if (!pTouchManager->IsSendingDelayedEvent())
127                 {
128                         return false;
129                 }
130
131                 result r = pTouchManager->AddPoint(touchinfo.GetPointId(), touchinfo.GetCurrentPosition(), _TOUCH_MOVED);
132                 if (r != E_SUCCESS)
133                 {
134                         return true;
135                 }
136
137                 return false;
138         }
139
140         virtual bool OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
141         {
142                 _TouchManager*  pTouchManager = _TouchManager::GetInstance();
143                 SysTryReturn(NID_UI, pTouchManager, false, E_SYSTEM, "[E_SYSTEM] _TouchManager does not exist.");
144
145                 if (pTouchManager->IsTouchCanceledOnGestureSuccess() == false)
146                 {
147                         CancelGesture(source, touchinfo);
148                 }
149
150                 _ITouchEventListener* pTouchedControlEventListener = source.GetPropagatedTouchEventListener();
151
152                 if (pTouchedControlEventListener != null)
153                 {
154                         pTouchManager->SetTouchAllowed(false);
155                         pTouchManager->ResetTouchInfo();
156                 }
157
158                 return false;
159         }
160
161 private:
162         void CancelGesture(const _Control& source, const _TouchInfo& touchinfo)
163         {
164                 IListT <_TouchGestureDetector*>* pGestureList = source.GetGestureDetectorList();
165
166                 if (pGestureList)
167                 {
168                         IEnumeratorT<_TouchGestureDetector*>* pEnumerator = pGestureList->GetEnumeratorN();
169
170                         if (pEnumerator)
171                         {
172                                 while(pEnumerator->MoveNext() == E_SUCCESS)
173                                 {
174                                                 _TouchGestureDetector* pGestureDetector = null;
175                                                 pEnumerator->GetCurrent(pGestureDetector);
176
177                                                 if (pGestureDetector == null)
178                                                 {
179                                                         continue;
180                                                 }
181
182                                                 if (pGestureDetector->IsGestureStarted())
183                                                 {
184                                                         pGestureDetector->SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_CANCELED);
185                                                         pGestureDetector->ProcessPublicListener(*pGestureDetector);
186                                                         pGestureDetector->ProcessCoreListener(*pGestureDetector);
187                                                 }
188                                                 else
189                                                 {
190                                                         pGestureDetector->SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_CANCELED);
191                                                 }
192
193                                                 pGestureDetector->OnTouchCanceled(source, touchinfo);
194                                 }
195                                 delete pEnumerator;
196                         }
197                 }
198         }
199 };
200 }
201
202 namespace Tizen { namespace Ui
203 {
204
205 _MultiFingerInfo::_MultiFingerInfo(void)
206         : __currentPointId(0)
207         , __generatedPointId(0)
208         , __pointCount(0)
209         , __pFingerInfoMap(null)
210 {
211         __pFingerInfoMap = new (std::nothrow) HashMapT<int, _FingerInfo*>;
212         SysTryReturnVoidResult(NID_UI, __pFingerInfoMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
213         SysTryCatch(NID_UI, __pFingerInfoMap->Construct() == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] System error occurred.");
214         return;
215
216 CATCH:
217         delete __pFingerInfoMap;
218         __pFingerInfoMap = null;
219         return;
220 }
221
222 _MultiFingerInfo::~_MultiFingerInfo(void)
223 {
224         RemoveFingerInfoList();
225 }
226
227 void
228 _MultiFingerInfo::RemoveFingerInfoList(void)
229 {
230         IMapEnumeratorT<int, _FingerInfo*>* pEnumerator = __pFingerInfoMap->GetMapEnumeratorN();
231         if (pEnumerator)
232         {
233                 while(pEnumerator->MoveNext() == E_SUCCESS)
234                 {
235                         _FingerInfo* pFingerInfo = null;
236                         pEnumerator->GetValue(pFingerInfo);
237
238                         if (pFingerInfo)
239                         {
240                                 delete pFingerInfo;
241                         }
242
243                 }
244                 delete pEnumerator;
245         }
246
247         __pFingerInfoMap->RemoveAll();
248         delete __pFingerInfoMap;
249         __pFingerInfoMap = null;
250 }
251
252 unsigned long
253 _MultiFingerInfo::GeneratePointId(unsigned long deviceId)
254 {
255         if (__pointCount == 0)
256         {
257                 InitializeFingerInfo();
258         }
259
260         _FingerInfo* pFingerInfo = null;
261         __pFingerInfoMap->GetValue(deviceId, pFingerInfo);
262
263         unsigned int pointId = 0;
264         pointId = __generatedPointId;
265
266         if (pFingerInfo == null)
267         {
268                 pFingerInfo = new (std::nothrow) _FingerInfo;
269                 SysTryReturn(NID_UI, pFingerInfo, INVALID_POINT_ID, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] GeneratePointId - Memory allocation failed.");
270
271                 pFingerInfo->SetDeviceId(deviceId);
272                 pFingerInfo->SetPointId(pointId);
273                 __pFingerInfoMap->Add(deviceId, pFingerInfo);
274         }
275         else
276         {
277                 pFingerInfo->SetDeviceId(deviceId);
278                 pFingerInfo->SetPointId(pointId);
279                 __pFingerInfoMap->SetValue(deviceId, pFingerInfo);
280         }
281
282         __currentPointId = pointId;
283         __generatedPointId++;
284         return pointId;
285
286 }
287
288 unsigned long
289 _MultiFingerInfo::GetPointId(unsigned long deviceId) const
290 {
291         _FingerInfo* pFingerInfo = null;
292         __pFingerInfoMap->GetValue(deviceId, pFingerInfo);
293         SysTryReturn(NID_UI, pFingerInfo, INVALID_POINT_ID, E_SYSTEM, "[E_SYTSTEM] pFingerInfo is null.");
294
295         return pFingerInfo->GetPointId();
296 }
297
298 unsigned long
299 _MultiFingerInfo::GetCurrentPointId(void) const
300 {
301         return __currentPointId;
302 }
303
304 Point
305 _MultiFingerInfo::GetPosition(unsigned long id) const
306 {
307         Point errorPoint(-1, -1);
308
309         IListT<_FingerInfo*>* pFingerList = __pFingerInfoMap->GetValuesN();
310         if (pFingerList)
311         {
312                 IEnumeratorT<_FingerInfo*>* pEnumerator = pFingerList->GetEnumeratorN();
313                 if (pEnumerator)
314                 {
315                         while(pEnumerator->MoveNext() == E_SUCCESS)
316                         {
317                                 _FingerInfo* pFingerInfo = null;
318                                 pEnumerator->GetCurrent(pFingerInfo);
319
320                                 if (pFingerInfo == null)
321                                 {
322                                         continue;
323                                 }
324
325                                 if (pFingerInfo->GetPointId() == id)
326                                 {
327                                         delete pEnumerator;
328                                         delete pFingerList;
329                                         return pFingerInfo->GetPoint();
330                                 }
331                         }
332                         delete pEnumerator;
333                 }
334                 delete pFingerList;
335         }
336
337         return errorPoint;
338 }
339
340 Point
341 _MultiFingerInfo::GetScreenPoint(unsigned long id) const
342 {
343         Point errorPoint(-1, -1);
344
345         IListT<_FingerInfo*>* pFingerList = __pFingerInfoMap->GetValuesN();
346         if (pFingerList)
347         {
348                 IEnumeratorT<_FingerInfo*>* pEnumerator = pFingerList->GetEnumeratorN();
349                 if (pEnumerator)
350                 {
351                         while(pEnumerator->MoveNext() == E_SUCCESS)
352                         {
353                                 _FingerInfo* pFingerInfo = null;
354                                 pEnumerator->GetCurrent(pFingerInfo);
355
356                                 if (pFingerInfo == null)
357                                 {
358                                         continue;
359                                 }
360
361                                 if (pFingerInfo->GetPointId() == id)
362                                 {
363                                         delete pEnumerator;
364                                         delete pFingerList;
365                                         return pFingerInfo->GetScreenPoint();
366                                 }
367                         }
368                         delete pEnumerator;
369                 }
370                 delete pFingerList;
371         }
372
373         return errorPoint;
374 }
375
376 Point
377 _MultiFingerInfo::GetStartPoint(unsigned long id) const
378 {
379         Point errorPoint(-1, -1);
380
381         IListT<_FingerInfo*>* pFingerList = __pFingerInfoMap->GetValuesN();
382         if (pFingerList)
383         {
384                 IEnumeratorT<_FingerInfo*>* pEnumerator = pFingerList->GetEnumeratorN();
385                 if (pEnumerator)
386                 {
387                         while(pEnumerator->MoveNext() == E_SUCCESS)
388                         {
389                                 _FingerInfo* pFingerInfo = null;
390                                 pEnumerator->GetCurrent(pFingerInfo);
391
392                                 if (pFingerInfo == null)
393                                 {
394                                         continue;
395                                 }
396
397                                 if (pFingerInfo->GetPointId() == id)
398                                 {
399                                         delete pEnumerator;
400                                         delete pFingerList;
401                                         return pFingerInfo->GetStartPoint();
402                                 }
403                         }
404                         delete pEnumerator;
405                 }
406                 delete pFingerList;
407         }
408
409         return errorPoint;
410 }
411
412 _TouchStatus
413 _MultiFingerInfo::GetStatus(unsigned long id) const
414 {
415         IListT<_FingerInfo*>* pFingerList = __pFingerInfoMap->GetValuesN();
416         if (pFingerList)
417         {
418                 IEnumeratorT<_FingerInfo*>* pEnumerator = pFingerList->GetEnumeratorN();
419                 if (pEnumerator)
420                 {
421                         while(pEnumerator->MoveNext() == E_SUCCESS)
422                         {
423                                 _FingerInfo* pFingerInfo = null;
424                                 pEnumerator->GetCurrent(pFingerInfo);
425
426                                 if (pFingerInfo == null)
427                                 {
428                                         continue;
429                                 }
430
431                                 if (pFingerInfo->GetPointId() == id)
432                                 {
433                                         delete pEnumerator;
434                                         delete pFingerList;
435                                         return pFingerInfo->GetStatus();
436                                 }
437                         }
438                         delete pEnumerator;
439                 }
440                 delete pFingerList;
441         }
442
443         return _TOUCH_PRESSED;
444 }
445
446 int
447 _MultiFingerInfo::GetPointCount(void) const
448 {
449         return __pointCount;
450 }
451
452 IListT<_FingerInfo*>*
453 _MultiFingerInfo::GetMultiFingerListN(void) const
454 {
455         IListT<_FingerInfo*>* pFingerInfoMapList = __pFingerInfoMap->GetValuesN();
456         SysTryReturn(NID_UI, pFingerInfoMapList, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
457
458         return pFingerInfoMapList;
459 }
460
461 void
462 _MultiFingerInfo::ResetFingerInfo(void)
463 {
464         __pointCount = 0;
465         __currentPointId = 0;
466         __generatedPointId = 0;
467 }
468
469 void
470 _MultiFingerInfo::InitializeFingerInfo(void)
471 {
472         IListT<_FingerInfo*>* pFingerList = __pFingerInfoMap->GetValuesN();
473
474         if (pFingerList)
475         {
476                 IEnumeratorT<_FingerInfo*>* pEnumerator = pFingerList->GetEnumeratorN();
477                 if (pEnumerator)
478                 {
479                         while(pEnumerator->MoveNext() == E_SUCCESS)
480                         {
481                                 _FingerInfo* pFingerInfo = null;
482                                 pEnumerator->GetCurrent(pFingerInfo);
483
484                                 if (pFingerInfo == null)
485                                 {
486                                         continue;
487                                 }
488
489                                 pFingerInfo->SetStatus(_TOUCH_FOCUS_OUT);
490                                 pFingerInfo->SetPointId(INVALID_POINT_ID);
491                                 __pFingerInfoMap->SetValue(pFingerInfo->GetDeviceId(), pFingerInfo);
492                         }
493                         delete pEnumerator;
494                 }
495                 delete pFingerList;
496         }
497 }
498
499 result
500 _MultiFingerInfo::SetFingerInfo(unsigned long pointId, const Point& point, const Point& screenPoint, const _TouchStatus status)
501 {
502         _FingerInfo* pFingerInfo = null;
503
504         IListT<_FingerInfo*>* pFingerList = __pFingerInfoMap->GetValuesN();
505         if (pFingerList)
506         {
507                 IEnumeratorT<_FingerInfo*>* pEnumerator = pFingerList->GetEnumeratorN();
508                 if (pEnumerator)
509                 {
510                         while(pEnumerator->MoveNext() == E_SUCCESS)
511                         {
512                                 pEnumerator->GetCurrent(pFingerInfo);
513                                 if (pFingerInfo == null)
514                                 {
515                                         continue;
516                                 }
517
518                                 if (pFingerInfo->GetPointId() == pointId)
519                                 {
520                                         break;
521                                 }
522                                 pFingerInfo = null;
523                         }
524                         delete pEnumerator;
525                 }
526                 delete pFingerList;
527         }
528
529         SysTryReturnResult(NID_UI, pFingerInfo, E_INVALID_CONDITION, "[E_INVALID_CONDITION] pFingerInfo is null");
530
531         switch (status)
532         {
533         case _TOUCH_PRESSED:
534                 pFingerInfo->SetStartPoint(screenPoint);
535                 pFingerInfo->SetPoint(screenPoint, point);
536                 pFingerInfo->SetStatus(_TOUCH_PRESSED);
537                 pFingerInfo->SetMoveReady(false);
538                 __pointCount++;
539                 break;
540
541         case _TOUCH_MOVED:
542                 if (pFingerInfo->GetStatus() == _TOUCH_RELEASED || pFingerInfo->GetStatus() == _TOUCH_FOCUS_OUT || pFingerInfo->GetPoint() == point)
543                 {
544                         return E_INVALID_CONDITION;
545                 }
546
547                 pFingerInfo->SetPoint(screenPoint, point);
548                 pFingerInfo->SetStatus(_TOUCH_MOVED);
549                 break;
550
551         case _TOUCH_RELEASED:
552                 if (pFingerInfo->GetStatus() == _TOUCH_RELEASED || pFingerInfo->GetStatus() == _TOUCH_FOCUS_OUT)
553                 {
554                         SysLog(NID_UI,"OnTouchReleased without OnTouchPressed");
555                         ResetFingerInfo();
556                         return E_INVALID_CONDITION;
557                 }
558
559                 pFingerInfo->SetPoint(screenPoint, point);
560                 pFingerInfo->SetStatus(_TOUCH_RELEASED);
561                 pFingerInfo->SetMoveReady(false);
562                 __pointCount--;
563
564                 if (__pointCount == 0 )
565                 {
566                         __currentPointId = 0;
567                         __generatedPointId = 0;
568                 }
569                 break;
570
571         default:
572                 break;
573         }
574
575         __pFingerInfoMap->SetValue(pFingerInfo->GetDeviceId(), pFingerInfo);
576         return E_SUCCESS;
577 }
578
579 _TouchManager* _TouchManager::__pInstance = null;
580
581 _TouchManager::_TouchManager(void)
582         : __pMultiFingerInfo(null)
583         , __touchCanceled(false)
584         , __touchAllowed(true)
585         , __pTouchEventListener(null)
586         , __captureAllowOutOfBounds(false)
587         , __isSendingDelayedEvent(true)
588         , __touchCanceledOnGestureSuccess(false)
589 {
590         ClearLastResult();
591
592         result r = E_SUCCESS;
593         _UiEventManager* pEventManager = null;
594
595         __pMultiFingerInfo = new (std::nothrow) _MultiFingerInfo;
596         SysTryReturnVoidResult(NID_UI, __pMultiFingerInfo, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
597
598         __pTouchEventListener = new (std::nothrow) _TouchEventListener;
599         SysTryCatch(NID_UI, __pTouchEventListener, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
600
601         pEventManager = _UiEventManager::GetInstance();
602         SysTryCatch(NID_UI, pEventManager, , E_SYSTEM, "[E_SYSTEM] _UiEventManager does not exist.");
603
604         r = pEventManager->AddTouchEventListener(*__pTouchEventListener);
605         SysTryCatch(NID_UI, r == E_SUCCESS, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
606
607         return;
608
609 CATCH:
610         delete __pMultiFingerInfo;
611         __pMultiFingerInfo = null;
612
613         if (__pTouchEventListener)
614         {
615                 delete __pTouchEventListener;
616                 __pTouchEventListener = null;
617         }
618 }
619
620 _TouchManager::~_TouchManager(void)
621 {
622         delete __pMultiFingerInfo;
623         __pMultiFingerInfo = null;
624
625         _UiEventManager* pEventManager = _UiEventManager::GetInstance();
626         if (pEventManager)
627         {
628                 pEventManager->RemoveTouchEventListener(*__pTouchEventListener);
629         }
630
631         delete __pTouchEventListener;
632         __pTouchEventListener = null;
633 }
634
635 void
636 _TouchManager::Initialize(void)
637 {
638         static pthread_once_t once_block = PTHREAD_ONCE_INIT;
639
640         if (__pInstance == null)
641         {
642                 pthread_once(&once_block, InitializeInstance);
643         }
644
645 }
646
647 _TouchManager*
648 _TouchManager::GetInstance(void)
649 {
650         return __pInstance;
651 }
652
653 void
654 _TouchManager::InitializeInstance(void)
655 {
656         ClearLastResult();
657
658         if (__pInstance == null)
659 {
660         __pInstance = new (std::nothrow) _TouchManager;
661         SysTryReturnVoidResult(NID_UI, __pInstance != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
662 }
663 }
664
665 void
666 _TouchManager::ReleaseInstance(void)
667 {
668         if (__pInstance)
669         {
670                 delete __pInstance;
671                 __pInstance = null;
672         }
673 }
674
675 result
676 _TouchManager::AddPoint(unsigned long pointId, const Point& point, _TouchStatus status)
677 {
678         Point screenPos(point.x, point.y);
679         Point controlPos(0, 0);
680
681         _Control* pControl = GetTouchControlSource();
682         if (pControl)
683         {
684                 controlPos.x = pControl->GetAbsoluteBounds().x;
685                 controlPos.y = pControl->GetAbsoluteBounds().y;
686
687                 screenPos.x += controlPos.x;
688                 screenPos.y += controlPos.y;
689         }
690
691         return __pMultiFingerInfo->SetFingerInfo(pointId, point, screenPos, status);
692 }
693
694 unsigned long
695 _TouchManager::GetPointId(unsigned long deviceId) const
696 {
697         return __pMultiFingerInfo->GetPointId(deviceId);
698 }
699
700 Tizen::Graphics::Point
701 _TouchManager::GetStartPoint(unsigned long pointId) const
702 {
703         return __pMultiFingerInfo->GetStartPoint(pointId);
704 }
705
706 unsigned long
707 _TouchManager::GetCurrentPointId(void) const
708 {
709         return __pMultiFingerInfo->GetCurrentPointId();
710 }
711
712 unsigned long
713 _TouchManager::GeneratePointId(const unsigned long deviceId) const
714 {
715         return __pMultiFingerInfo->GeneratePointId(deviceId);
716 }
717
718 Point
719 _TouchManager::GetPosition(unsigned long id) const
720 {
721         return __pMultiFingerInfo->GetPosition(id);
722 }
723
724 Point
725 _TouchManager::GetScreenPoint(unsigned long id) const
726 {
727         return __pMultiFingerInfo->GetScreenPoint(id);
728 }
729
730 TouchStatus
731 _TouchManager::GetTouchStatus(const unsigned long id) const
732 {
733         return (static_cast <TouchStatus>(__pMultiFingerInfo->GetStatus(id)));
734 }
735
736  int
737  _TouchManager::GetPointCount(void) const
738  {
739         return __pMultiFingerInfo->GetPointCount();
740  }
741
742 void
743 _TouchManager::SetTouchControlSource(const _Control& source)
744 {
745         __touchControlHandle = source.GetHandle();
746 }
747
748 _Control*
749 _TouchManager::GetTouchControlSource(void) const
750 {
751         _ControlManager* pControlManager = _ControlManager::GetInstance();
752         SysTryReturn(NID_UI, pControlManager, null, E_SYSTEM, "[E_SYSTEM] _ControlManager does not exist.");
753
754         return pControlManager->GetObject(__touchControlHandle);
755 }
756
757 void
758 _TouchManager::SetFocusedControlSource(const _Control& source)
759 {
760         __focusedControlHandle = source.GetHandle();
761 }
762
763 _Control*
764 _TouchManager::GetFocusedControlSource(void) const
765 {
766         _ControlManager* pControlManager = _ControlManager::GetInstance();
767         SysTryReturn(NID_UI, pControlManager, null, E_SYSTEM, "[E_SYSTEM] _ControlManager does not exist.");
768
769         return pControlManager->GetObject(__focusedControlHandle);
770 }
771
772 result
773 _TouchManager::SendEvent(_Control* pControl, const _TouchInfo& touchInfo)
774 {
775         SysTryReturnResult(NID_UI, pControl, E_INVALID_ARG, "[E_INVALID_ARG] pControl is null.");
776
777         _UiTouchEvent event(pControl->GetHandle(), touchInfo, _UI_EVENT_ROUTE_DIRECT);
778
779         _Control* pTouchedControl = GetTouchControlSource();
780         if (pTouchedControl)
781         {
782                 event.SetOriginalDestination(*pTouchedControl);
783         }
784
785         _UiEventManager* pEventManager = _UiEventManager::GetInstance();
786         SysTryReturnResult(NID_UI, pEventManager, E_SYSTEM, "[E_SYSTEM] _UiEventManager does not exist.");
787
788         __isSendingDelayedEvent = false;
789         result r = pEventManager->SendEvent(event);
790         __isSendingDelayedEvent = true;
791
792         return r;
793 }
794
795 void
796 _TouchManager::SetTouchCanceled(bool canceled, bool onlyTouchEvent)
797 {
798         __touchCanceledOnGestureSuccess = onlyTouchEvent;
799
800         if (canceled)
801         {
802                 if (GetTouchControlSource() && GetTouchControlSource()->IsAttachedToMainTree())
803                 {
804                         Point currentPoint(0, 0);
805                         _TouchInfo touchInfo;
806
807                         if (GetTouchControlSource()->IsMultiTouchEnabled())
808                         {
809                                 currentPoint.x = GetScreenPoint(GetCurrentPointId()).x;
810                                 currentPoint.y = GetScreenPoint(GetCurrentPointId()).y;
811
812                                 _TouchInfo multiTouchInfo(GetCurrentPointId(), _TOUCH_CANCELED, currentPoint, false, 0);
813                                 touchInfo = multiTouchInfo;
814                         }
815                         else
816                         {
817                                 currentPoint.x = GetScreenPoint(SINGLE_POINT_ID).x;
818                                 currentPoint.y = GetScreenPoint(SINGLE_POINT_ID).y;
819
820                                 _TouchInfo singleTouchInfo(SINGLE_POINT_ID, _TOUCH_CANCELED, currentPoint, false, 0);
821                                 touchInfo = singleTouchInfo;
822                         }
823
824                         _UiTouchEvent event(GetTouchControlSource()->GetHandle(), touchInfo);
825
826                         _UiEventManager* pEventManager = _UiEventManager::GetInstance();
827                         SysTryReturnVoidResult(NID_UI, pEventManager, E_SYSTEM, "[E_SYSTEM] _UiEventManager does not exist.");
828
829                         pEventManager->SendEvent(event);
830                 }
831                 SetLastResult(E_SUCCESS);
832         }
833 }
834
835 bool
836 _TouchManager::IsTouchCanceledOnGestureSuccess(void) const
837 {
838         return __touchCanceledOnGestureSuccess;
839 }
840
841 void
842 _TouchManager::SetTouchCanceledOnGestureSuccess(bool cancel)
843 {
844         __touchCanceledOnGestureSuccess = cancel;
845 }
846
847 void
848 _TouchManager::SetTouchAllowed(bool allowed)
849 {
850         __touchAllowed = allowed;
851 }
852
853 bool
854 _TouchManager::IsTouchAllowed(void)
855 {
856         return __touchAllowed;
857 }
858
859 bool
860 _TouchManager::IsInTouchMoveAllowanceBounds(const _Control& source, const _TouchInfo& touchInfo)
861 {
862         IListT<_FingerInfo*>* pFingerInfoList = GetMultiFingerInfoListN();
863         SysTryReturn(NID_UI, pFingerInfoList, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
864
865         const int count = pFingerInfoList->GetCount();
866
867         for (int i = 0; i < count; i++)
868         {
869                 _FingerInfo* pFingerInfo = null;
870                 pFingerInfoList->GetAt(i, pFingerInfo);
871                 if (pFingerInfo == null)
872                 {
873                         continue;
874                 }
875
876                 if (pFingerInfo->GetPointId() == touchInfo.GetPointId())
877                 {
878                         if (pFingerInfo->GetMoveReady() == true)
879                         {
880                                 delete pFingerInfoList;
881                                 pFingerInfoList = null;
882                                 return true;
883                         }
884
885                         Point tmpPoint = GetStartPoint(touchInfo.GetPointId());
886                         Rectangle absBounds = source.GetAbsoluteBounds();
887
888                         Point startPoint(tmpPoint.x - absBounds.x, tmpPoint.y - absBounds.y);
889                         Point currentPoint = touchInfo.GetCurrentPosition();
890
891                         //SysLog(NID_UI, "[Touch Test] tmpPoint(%d, %d) absBounds(%d, %d) startPoint(%d, %d) currentPoint(%d, %d)",
892                         //      tmpPoint.x, tmpPoint.y, absBounds.x, absBounds.y, startPoint.x, startPoint.y, currentPoint.x, currentPoint.y);
893
894                         int distance =  int(hypot(abs(startPoint.x-currentPoint.x), abs(startPoint.y-currentPoint.y)));
895                         int touchMoveAllowanceBounds = 0;
896
897                         int allowanceBoundsValue[] = {3, 25, 50};
898                         touchMoveAllowanceBounds = allowanceBoundsValue[source.GetTouchMoveAllowance()];
899
900                         if (distance >= touchMoveAllowanceBounds)
901                         {
902                                 pFingerInfo->SetMoveReady(true);
903
904                                 delete pFingerInfoList;
905                                 return true;
906                         }
907                 }
908         }
909
910         delete pFingerInfoList;
911         return false;
912 }
913
914 void
915 _TouchManager::SetCapturedControl(const _Control* pControl, bool allowOutOfBounds)
916 {
917         if (pControl)
918         {
919                 __capturedControlHandle = pControl->GetHandle();
920         }
921         else
922         {
923                 __capturedControlHandle = _ControlHandle();
924         }
925
926         __captureAllowOutOfBounds = allowOutOfBounds;
927 }
928
929 _Control*
930 _TouchManager::GetCapturedControl(void) const
931 {
932         _ControlManager* pControlManager = _ControlManager::GetInstance();
933         SysTryReturn(NID_UI, pControlManager, null, E_SYSTEM, "[E_SYSTEM] _ControlManager does not exist.");
934
935         return pControlManager->GetObject(__capturedControlHandle);
936 }
937
938 bool
939 _TouchManager::IsCaptureAllowedOutOfBounds(void) const
940 {
941         return __captureAllowOutOfBounds;
942 }
943
944 void
945 _TouchManager::ResetTouchInfo(void)
946 {
947         __pMultiFingerInfo->ResetFingerInfo();
948
949         _Control* pControl = GetTouchControlSource();
950         if (pControl)
951         {
952                 IListT <_TouchGestureDetector*>* pGestureList = pControl->GetGestureDetectorList();
953
954                 if (pGestureList)
955                 {
956                         IEnumeratorT<_TouchGestureDetector*>* pEnumerator = pGestureList->GetEnumeratorN();
957
958                         if (pEnumerator)
959                         {
960                                 while(pEnumerator->MoveNext() == E_SUCCESS)
961                                 {
962                                                 _TouchGestureDetector* pGestureDetector = null;
963                                                 pEnumerator->GetCurrent(pGestureDetector);
964
965                                                 if (pGestureDetector == null)
966                                                 {
967                                                         continue;
968                                                 }
969
970                                                 pGestureDetector->SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_CANCELED);
971                                                 pGestureDetector->ProcessCoreListener(*pGestureDetector);
972                                 }
973                                 delete pEnumerator;
974                         }
975                 }
976         }
977
978         __touchAllowed = false;
979 }
980
981 IListT<_FingerInfo*>*
982 _TouchManager::GetMultiFingerInfoListN(void) const
983 {
984         return __pMultiFingerInfo->GetMultiFingerListN();
985 }
986
987 bool
988 _TouchManager::IsSendingDelayedEvent(void) const
989 {
990         return __isSendingDelayedEvent;
991 }
992 } } //Tizen::Ui