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