f7fe36187e86dc4c3daa5a0776d248cea6c20b72
[platform/framework/native/uifw.git] / src / ui / FUi_UiTouchEvent.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  * @file                FUi_UiTouchEvent.cpp
19  * @brief               This is the implementation file for the _UiTouchEvent class.
20  */
21
22 #include <FBaseResult.h>
23 #include <FBaseColIEnumeratorT.h>
24 #include <FBaseSysLog.h>
25 #include "FUi_UiTouchEvent.h"
26 #include "FUi_ITouchEventListener.h"
27 #include "FUi_ITouchEventPreviewer.h"
28 #include "FUi_Control.h"
29 #include "FUi_ControlManager.h"
30 #include "FUi_TouchGestureDetector.h"
31 #include "FUi_TouchManager.h"
32 #include "FUi_ITouchGestureDelegate.h"
33 #include "FUi_ControlImpl.h"
34 #include "FUi_TouchEventArg.h"
35 #include "FUi_ControlManager.h"
36 #include "FUi_CoordinateSystemUtils.h"
37
38 extern "C" {
39 extern void _UiPrintControl(const Tizen::Ui::_Control& control, bool printChildren);
40 }
41
42
43 using namespace std::tr1;
44 using namespace Tizen::Base::Collection;
45 using namespace Tizen::Graphics;
46
47 namespace Tizen { namespace Ui
48 {
49 _TouchInfo::_TouchInfo(void)
50         : __pointId(0)
51         , __touchStatus(_TOUCH_PRESSED)
52         , __currentPosition(0, 0)
53         , __isFlicked(false)
54         , __timeStamp(0)
55 {
56 }
57
58 _TouchInfo::_TouchInfo(unsigned long pointId, _TouchStatus status, const Tizen::Graphics::Point& current, const bool isFlick, long long timeStamp)
59         : __pointId(pointId)
60         , __touchStatus(status)
61         , __isFlicked(isFlick)
62         , __timeStamp(timeStamp)
63 {
64         __currentPosition = _CoordinateSystemUtils::ConvertToFloat(current);
65 }
66
67 _TouchInfo::_TouchInfo(unsigned long pointId, _TouchStatus status, const Tizen::Graphics::FloatPoint& current, const bool isFlick, long long timeStamp)
68         : __pointId(pointId)
69         , __touchStatus(status)
70         , __currentPosition(current)
71         , __isFlicked(isFlick)
72         , __timeStamp(timeStamp)
73 {
74 }
75
76 _TouchInfo::_TouchInfo(const _TouchInfo& rhs)
77         : __pointId(rhs.__pointId)
78         , __touchStatus(rhs.__touchStatus)
79         , __currentPosition(rhs.__currentPosition)
80         , __isFlicked(rhs.__isFlicked)
81         , __timeStamp(rhs.__timeStamp)
82 {
83 }
84
85 _TouchInfo&
86 _TouchInfo::operator =(const _TouchInfo& rhs)
87 {
88         if (this != &rhs)
89         {
90                 __pointId = rhs.__pointId;
91                 __touchStatus = rhs.__touchStatus;
92                 __currentPosition = rhs.__currentPosition;
93                 __isFlicked = rhs.__isFlicked;
94                 __timeStamp = rhs.__timeStamp;
95         }
96
97         return *this;
98 }
99
100 _TouchInfo::~_TouchInfo(void)
101 {
102 }
103
104 _TouchStatus
105 _TouchInfo::GetTouchStatus(void) const
106 {
107         return __touchStatus;
108 }
109
110 Tizen::Graphics::FloatPoint
111 _TouchInfo::GetCurrentPosition(void) const
112 {
113         return __currentPosition;
114 }
115
116 unsigned long
117 _TouchInfo::GetPointId(void) const
118 {
119         return __pointId;
120 }
121
122 bool
123 _TouchInfo::IsFlicked(void) const
124 {
125         return __isFlicked;
126 }
127
128 long long
129 _TouchInfo::GetTimeStamp(void) const
130 {
131         return __timeStamp;
132 }
133
134 void
135 _TouchInfo::SetTouchInfo(unsigned long pointId, _TouchStatus status, Tizen::Graphics::Point& current, bool isFlick, long long timeStamp)
136 {
137         __pointId = pointId;
138         __touchStatus = status;
139         __currentPosition = _CoordinateSystemUtils::ConvertToFloat(current);
140         __isFlicked = isFlick;
141         __timeStamp = timeStamp;
142 }
143
144 void
145 _TouchInfo::SetTouchInfo(unsigned long pointId, _TouchStatus status, Tizen::Graphics::FloatPoint& current, bool isFlick, long long timeStamp)
146 {
147         __pointId = pointId;
148         __touchStatus = status;
149         __currentPosition = current;
150         __isFlicked = isFlick;
151         __timeStamp = timeStamp;
152 }
153
154 _MouseInfo::_MouseInfo(void)
155         : __pointId(0)
156         , __touchStatus(_TOUCH_PRESSED)
157         , __currentPosition(0, 0)
158         , __zAxis(0)
159         , __buttons(0)
160         , __isFlicked(false)
161         , __timeStamp(0)
162 {
163 }
164
165 _MouseInfo::_MouseInfo(unsigned long pointId, _TouchStatus status, const Tizen::Graphics::FloatPoint& current, int zAxis, int buttons, const bool isFlick, long long timeStamp)
166         : __pointId(pointId)
167         , __touchStatus(status)
168         , __currentPosition(current)
169         , __zAxis(zAxis)
170         , __buttons(buttons)
171         , __isFlicked(isFlick)
172         , __timeStamp(timeStamp)
173 {
174 }
175
176 _MouseInfo::_MouseInfo(const _MouseInfo& rhs)
177         : __pointId(rhs.__pointId)
178         , __touchStatus(rhs.__touchStatus)
179         , __currentPosition(rhs.__currentPosition)
180         , __zAxis(rhs.__zAxis)
181         , __buttons(rhs.__buttons)
182         , __isFlicked(rhs.__isFlicked)
183         , __timeStamp(rhs.__timeStamp)
184 {
185 }
186
187 _MouseInfo&
188 _MouseInfo::operator =(const _MouseInfo& rhs)
189 {
190         if (this != &rhs)
191         {
192                 __pointId = rhs.__pointId;
193                 __touchStatus = rhs.__touchStatus;
194                 __currentPosition = rhs.__currentPosition;
195                 __zAxis = rhs.__zAxis;
196                 __buttons = rhs.__buttons;
197                 __isFlicked = rhs.__isFlicked;
198                 __timeStamp = rhs.__timeStamp;
199         }
200
201         return *this;
202 }
203
204 _MouseInfo::~_MouseInfo(void)
205 {
206 }
207
208 _TouchStatus
209 _MouseInfo::GetTouchStatus(void) const
210 {
211         return __touchStatus;
212 }
213
214 Tizen::Graphics::FloatPoint
215 _MouseInfo::GetCurrentPosition(void) const
216 {
217         return __currentPosition;
218 }
219
220 unsigned long
221 _MouseInfo::GetPointId(void) const
222 {
223         return __pointId;
224 }
225
226 int
227 _MouseInfo::GetZAxis(void) const
228 {
229         return __zAxis;
230 }
231
232 int
233 _MouseInfo::GetButtons(void) const
234 {
235         return __buttons;
236 }
237
238 bool
239 _MouseInfo::IsFlicked(void) const
240 {
241         return __isFlicked;
242 }
243
244 long long
245 _MouseInfo::GetTimeStamp(void) const
246 {
247         return __timeStamp;
248 }
249
250 void
251 _MouseInfo::SetTouchInfo(unsigned long pointId, _TouchStatus status, Tizen::Graphics::Point& current, int zAxis, int buttons, bool isFlick, long long timeStamp)
252 {
253         __pointId = pointId;
254         __touchStatus = status;
255         __currentPosition = _CoordinateSystemUtils::ConvertToFloat(current);
256         __zAxis = zAxis;
257         __buttons = buttons;
258         __isFlicked = isFlick;
259         __timeStamp = timeStamp;
260 }
261
262 void
263 _MouseInfo::SetTouchInfo(unsigned long pointId, _TouchStatus status, Tizen::Graphics::FloatPoint& current, int zAxis, int buttons, bool isFlick, long long timeStamp)
264 {
265         __pointId = pointId;
266         __touchStatus = status;
267         __currentPosition = current;
268         __zAxis = zAxis;
269         __buttons = buttons;
270         __isFlicked = isFlick;
271         __timeStamp = timeStamp;
272 }
273
274 _UiTouchEvent::_UiTouchEvent(const _UiObjectHandle& destination, const _TouchInfo& touchInfo, _UiEventRouteType routeType, const _UiObjectHandle& source)
275         : _UiEvent(destination, source, routeType)
276         , __touchInfo(touchInfo)
277         , __pForcedControlList(new (std::nothrow) LinkedListT<_Control*>)
278 {
279 }
280
281 _UiTouchEvent::~_UiTouchEvent(void)
282 {
283 }
284
285 _UiTouchEvent::_UiTouchEvent(const _UiTouchEvent& rhs)
286         : _UiEvent(rhs)
287         , __touchInfo(rhs.__touchInfo)
288         , __pForcedControlList(rhs.__pForcedControlList)
289 {
290 }
291
292 _UiTouchEvent&
293 _UiTouchEvent::operator =(const _UiTouchEvent& rhs)
294 {
295         _UiEvent::operator =(rhs);
296
297         if (this != &rhs)
298         {
299                 __touchInfo = rhs.__touchInfo;
300                 __pForcedControlList = rhs.__pForcedControlList;
301         }
302
303         return *this;
304 }
305
306 const _TouchInfo*
307 _UiTouchEvent::GetTouchInfo(void) const
308 {
309         return &__touchInfo;
310 }
311
312 _UiTouchEvent*
313 _UiTouchEvent::CloneN(void) const
314 {
315         return new (std::nothrow) _UiTouchEvent(*this);
316 }
317
318 _UiEventType
319 _UiTouchEvent::GetEventType(void) const
320 {
321         return _UI_EVENT_TOUCH;
322 }
323
324 bool
325 _UiTouchEvent::IsEventEnabled(const _Control& control) const
326 {
327         if (!_UiEvent::IsEventEnabled(control))
328         {
329                 return false;
330         }
331
332         if (GetTouchInfo()->GetTouchStatus() != _TOUCH_CANCELED)
333         {
334                 if (!control.IsInputEventEnabled())
335                 {
336                         return false;
337                 }
338         }
339
340         return true;
341 }
342
343 result
344 _UiTouchEvent::OnPreviewEventProcessing(const _Control& control, bool& isFiltered)
345 {
346         result r = E_SUCCESS;
347
348         const _TouchInfo* pTouchInfo = GetTouchInfo();
349         SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
350
351         if ((!ExistGlobalGesture() || GetAccessibilityEvent()) && !isFiltered)
352         {
353                 _ITouchEventPreviewer* pTouchEventPreviewer = control.GetPropagatedTouchEventListener();
354                 SysTryReturn(NID_UI, pTouchEventPreviewer, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
355
356                 r = FirePreviewListener(pTouchEventPreviewer, &control, isFiltered);
357         }
358
359         return r;
360 }
361
362 result
363 _UiTouchEvent::OnEventProcessing(const _Control& control, bool& isFiltered)
364 {
365         result r = E_SUCCESS;
366
367         bool doesControlExist = false;
368
369         const _TouchInfo* pTouchInfo = GetTouchInfo();
370         SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
371
372         if ((!ExistGlobalGesture() || GetAccessibilityEvent()) && !isFiltered)
373         {
374                 ProcessGesture(control, isFiltered);
375         }
376         else if (isFiltered)
377         {
378                 doesControlExist = __pForcedControlList->Contains(const_cast<_Control*>(&control));
379
380                 if (doesControlExist)
381                 {
382                         bool isForcedFiltered = false;
383                         ProcessGesture(control, isForcedFiltered);
384
385                         if (isForcedFiltered)
386                         {
387                                 isFiltered = true;
388                         }
389                 }
390         }
391
392         if (!ExistGlobalGesture() || GetAccessibilityEvent())
393         {
394                 if(!isFiltered || doesControlExist)
395                 {
396                         _ITouchEventListener* pTouchEventListener = control.GetPropagatedTouchEventListener();
397                         SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
398
399                         r = FireListener(pTouchEventListener, &control, true, isFiltered);
400                 }
401         }
402
403         return r;
404 }
405
406 result
407 _UiTouchEvent::OnListenerProcessing(const _IUiEventListener& listener, bool& isFiltered)
408 {
409         _ITouchEventListener* pTouchEventListener = dynamic_cast <_ITouchEventListener*>(const_cast <_IUiEventListener*>(&listener));
410         SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
411
412         return FireListener(pTouchEventListener, null, true, isFiltered);
413 }
414
415 result
416 _UiTouchEvent::OnEventHandled(const _Control& control)
417 {
418         _Control* pTarget = const_cast<_Control*>(GetControl(GetDestination()));
419         SysTryReturn(NID_UI, pTarget, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
420
421         const _TouchInfo* pTouchInfo = GetTouchInfo();
422         SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
423
424         result r = E_SUCCESS;
425
426         switch (pTouchInfo->GetTouchStatus())
427         {
428         case _TOUCH_PRESSED:
429                 pTarget->GetPropagatedTouchEventListener()->OnTouchPressHandled(control);
430                 break;
431
432         case _TOUCH_MOVED:
433                 pTarget->GetPropagatedTouchEventListener()->OnTouchMoveHandled(control);
434                 break;
435
436         case _TOUCH_RELEASED:
437                 pTarget->GetPropagatedTouchEventListener()->OnTouchReleaseHandled(control);
438                 break;
439
440         case _TOUCH_CANCELED:
441                 pTarget->GetPropagatedTouchEventListener()->OnTouchCancelHandled(control);
442                 break;
443
444         default:
445                 r = E_SYSTEM;
446                 break;
447         }
448
449         return r;
450 }
451
452 result
453 _UiTouchEvent::FireListener(const _ITouchEventListener* pListener, const _Control* pControl, bool isTouchEvent, bool& isFiltered)
454 {
455         _ITouchEventListener* pTouchEventListener = const_cast <_ITouchEventListener*>(pListener);
456         SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
457
458         result r = E_SUCCESS;
459
460         const _TouchInfo* pTouchInfo = GetTouchInfo();
461         SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
462
463         const _Control* pTarget = GetControl(GetOriginalDestination());
464         if (pTarget == null)
465         {
466                 SysLog(NID_UI, "pTarget == null, Call ResetTouchInfo.");
467                 _TouchManager* pTouchManager = _TouchManager::GetInstance();
468                 pTouchManager->ResetTouchInfo();
469
470                 return E_SUCCESS;
471         }
472
473         if (ResetTouchInfo(pTarget, *pTouchInfo) == E_SUCCESS)
474         {
475                 isFiltered = true;
476                 return E_SYSTEM;
477         }
478
479         FloatPoint point(0, 0);
480
481         if (pControl)
482         {
483                 _TouchManager* pTouchManager = _TouchManager::GetInstance();
484                 SysAssert(pTouchManager != null)
485
486                 point = GetRelativePoint(*pControl, pTouchInfo->GetCurrentPosition());
487
488                 if (isTouchEvent && (pTouchInfo->GetTouchStatus() != _TOUCH_CANCELED))
489                 {
490                         if (!pTouchManager->IsTouchAllowed() || (pTouchManager->IsTouchAllowed() && pTouchManager->IsTouchCanceledOnGestureSuccess())
491                                 || (!pControl->IsMultiTouchEnabled() && pTouchInfo->GetPointId() > 0))
492                         {
493                                 isFiltered = true;
494                                 return E_SUCCESS;
495                         }
496                 }
497         }
498         else
499         {
500                 point = GetRelativePoint(*pTarget, pTouchInfo->GetCurrentPosition());
501         }
502
503         _TouchInfo touchInfo(pTouchInfo->GetPointId(), pTouchInfo->GetTouchStatus(), point, false, pTouchInfo->GetTimeStamp());
504
505         switch (touchInfo.GetTouchStatus())
506         {
507         case _TOUCH_PRESSED:
508                 isFiltered = pTouchEventListener->OnTouchPressed(*pTarget, touchInfo);
509                 break;
510
511         case _TOUCH_RELEASED:
512                 isFiltered = pTouchEventListener->OnTouchReleased(*pTarget, touchInfo);
513                 break;
514
515         case _TOUCH_MOVED:
516                 isFiltered = pTouchEventListener->OnTouchMoved(*pTarget, touchInfo);
517                 break;
518
519                 // 2.0 compatibility for touch simulate
520         case _TOUCH_LONG_PRESSED:
521                 // fall through
522         case _TOUCH_DOUBLE_PRESSED:
523                 {
524                         void* pData = pTarget->GetUserData();
525                         if (pData)
526                         {
527                                 _ControlImpl* pTargetImpl = static_cast<_ControlImpl*>(pData);
528                         if (pTargetImpl)
529                         {
530                                 pTargetImpl->GenerateTouchEvent(touchInfo);
531                         }
532                 }
533                 }
534                 break;
535
536         case _TOUCH_CANCELED:
537                 isFiltered = pTouchEventListener->OnTouchCanceled(*pTarget, touchInfo);
538                 break;
539
540         default:
541                 r = E_SYSTEM;
542         }
543
544         if (isFiltered)
545         {
546                 if (pControl)
547                 {
548                         SysLog(NID_UI, "Event Consumed : isFiltered is True : pControl %x", pControl);
549                         //_UiPrintControl(*pControl, false);
550                 }
551                 SysLog(NID_UI, "Event Consumed : isFiltered is True : pTarget %x", pTarget);
552         }
553
554         return r;
555 }
556
557 result
558 _UiTouchEvent::FirePreviewListener(const _ITouchEventPreviewer* pListener, const _Control* pControl, bool& isFiltered)
559 {
560         _ITouchEventPreviewer* pTouchEventPreviewer = const_cast <_ITouchEventPreviewer*>(pListener);
561         SysTryReturn(NID_UI, pTouchEventPreviewer, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
562
563         result r = E_SUCCESS;
564
565         const _TouchInfo* pTouchInfo = GetTouchInfo();
566         SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
567
568         const _Control* pTarget = GetControl(GetDestination());
569
570         FloatPoint point = GetRelativePoint(*pControl, pTouchInfo->GetCurrentPosition());
571
572         if (!pControl->IsMultiTouchEnabled() && pTouchInfo->GetPointId() > 0)
573         {
574                 isFiltered = false;
575                 return E_SUCCESS;
576         }
577
578         _TouchInfo touchInfo(pTouchInfo->GetPointId(), pTouchInfo->GetTouchStatus(), point, false, pTouchInfo->GetTimeStamp());
579
580         _UiTouchEventDelivery eventDelivery = _UI_TOUCH_EVENT_DELIVERY_NO;
581
582         //condition 1) if target is not enabled multi touch, point id should be 0
583         //2) target is enabled multi touch
584         switch (touchInfo.GetTouchStatus())
585         {
586         case _TOUCH_PRESSED:
587                 eventDelivery = pTouchEventPreviewer->OnPreviewTouchPressed(*pTarget, touchInfo);
588
589                 break;
590
591         case _TOUCH_RELEASED:
592                 eventDelivery = pTouchEventPreviewer->OnPreviewTouchReleased(*pTarget, touchInfo);
593
594                 break;
595
596         case _TOUCH_MOVED:
597                 eventDelivery = pTouchEventPreviewer->OnPreviewTouchMoved(*pTarget, touchInfo);
598
599                 break;
600
601         case _TOUCH_CANCELED:
602                 eventDelivery = pTouchEventPreviewer->OnPreviewTouchCanceled(*pTarget, touchInfo);
603                 break;
604
605         default:
606                 r = E_SYSTEM;
607                 break;
608         }
609
610         if (eventDelivery != _UI_TOUCH_EVENT_DELIVERY_NO)
611         {
612                 // isFiltered = (eventDelivery == _UI_TOUCH_EVENT_DELIVERY_FORCED_YES);
613
614                 // if (isFiltered)
615                 if (eventDelivery == _UI_TOUCH_EVENT_DELIVERY_FORCED_YES)
616                 {
617                         __pForcedControlList->Add(const_cast<_Control*>(pControl));
618                 }
619         }
620         else
621         {
622                 isFiltered = true;
623         }
624
625         return r;
626 }
627
628 result
629 _UiTouchEvent::ProcessGesture(const _Control& control, bool& isFiltered)
630 {
631         if (control.IsSendingDelayedEvent())
632         {
633                 return E_SUCCESS;
634         }
635
636         IListT<_TouchGestureDetector*>* pGestureList = control.GetGestureDetectorList();
637         if (!pGestureList || (pGestureList && (pGestureList->GetCount() <= 0)))
638         {
639                 return E_SUCCESS;
640         }
641
642         IEnumeratorT<_TouchGestureDetector*>* pEnumerator = pGestureList->GetEnumeratorN();
643         SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
644
645         while (pEnumerator->MoveNext() == E_SUCCESS)
646         {
647                 _TouchGestureDetector* pGestureDetector = null;
648                 pEnumerator->GetCurrent(pGestureDetector);
649
650                 if (!pGestureDetector)
651                 {
652                         continue;
653                 }
654
655                 _ITouchGestureDelegate* pDelegator = pGestureDetector->GetDelegate();
656                 if (pDelegator)
657                 {
658                         FireListener(pDelegator, &control, false, isFiltered);
659                 }
660         }
661
662         delete pEnumerator;
663         return E_SUCCESS;
664 }
665
666 FloatPoint
667 _UiTouchEvent::GetRelativePoint(const _Control& control, const FloatPoint& point) const
668 {
669         FloatPoint relativePoint(point);
670         FloatRectangle absRect = control.GetAbsoluteBoundsF();
671
672         relativePoint.x -= absRect.x;
673         relativePoint.y -= absRect.y;
674
675         return relativePoint;
676 }
677
678 result
679 _UiTouchEvent::ResetTouchInfo(const _Control* pControl, const _TouchInfo& touchInfo)
680 {
681         _TouchManager* pTouchManager = _TouchManager::GetInstance();
682         SysTryReturnResult(NID_UI, pTouchManager, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
683
684         if (pControl == null)
685         {
686                 if (touchInfo.GetTouchStatus() == _TOUCH_RELEASED)
687                 {
688                         pTouchManager->ResetTouchInfo();
689                 }
690
691                 return E_SUCCESS;
692         }
693
694         return E_INVALID_CONDITION;
695 }
696
697 bool
698 _UiTouchEvent::ExistGlobalGesture(void)
699 {
700         _ControlManager* pControlManager = _ControlManager::GetInstance();
701         SysTryReturn(NID_UI, pControlManager, false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
702
703         bool exist = false;
704
705         IListT<_TouchGestureDetector*>* pGestureList = pControlManager->GetGestureDetectorList();
706         if (pGestureList && (pGestureList->GetCount() > 0))
707         {
708                 exist = true;
709         }
710
711         return exist;
712 }
713
714 _UiMouseEvent::_UiMouseEvent(const _UiObjectHandle& destination, const _MouseInfo& mouseInfo, _UiEventRouteType routeType, const _UiObjectHandle& source)
715         : _UiEvent(destination, source, routeType)
716         , __mouseInfo(mouseInfo)
717         , __pForcedControlList(new (std::nothrow) LinkedListT<_Control*>)
718 {
719 }
720
721 _UiMouseEvent::~_UiMouseEvent(void)
722 {
723 }
724
725 _UiMouseEvent::_UiMouseEvent(const _UiMouseEvent& rhs)
726         : _UiEvent(rhs)
727         , __mouseInfo(rhs.__mouseInfo)
728         , __pForcedControlList(rhs.__pForcedControlList)
729 {
730 }
731
732 _UiMouseEvent&
733 _UiMouseEvent::operator =(const _UiMouseEvent& rhs)
734 {
735         _UiEvent::operator =(rhs);
736
737         if (this != &rhs)
738         {
739                 __mouseInfo = rhs.__mouseInfo;
740                 __pForcedControlList = rhs.__pForcedControlList;
741         }
742
743         return *this;
744 }
745
746 const _MouseInfo*
747 _UiMouseEvent::GetTouchInfo(void) const
748 {
749         return &__mouseInfo;
750 }
751
752 _UiMouseEvent*
753 _UiMouseEvent::CloneN(void) const
754 {
755         return new (std::nothrow) _UiMouseEvent(*this);
756 }
757
758 _UiEventType
759 _UiMouseEvent::GetEventType(void) const
760 {
761         return _UI_EVENT_TOUCH;
762 }
763
764 bool
765 _UiMouseEvent::IsEventEnabled(const _Control& control) const
766 {
767         if (!_UiEvent::IsEventEnabled(control))
768         {
769                 return false;
770         }
771
772         if (GetTouchInfo()->GetTouchStatus() != _TOUCH_CANCELED)
773         {
774                 if (!control.IsInputEventEnabled())
775                 {
776                         return false;
777                 }
778         }
779
780         return true;
781 }
782
783 result
784 _UiMouseEvent::OnPreviewEventProcessing(const _Control& control, bool& isFiltered)
785 {
786         result r = E_SUCCESS;
787
788         const _MouseInfo* pMouseInfo = GetTouchInfo();
789         SysTryReturn(NID_UI, pMouseInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
790
791         if ((!ExistGlobalGesture() || GetAccessibilityEvent()) && !isFiltered)
792         {
793                 _ITouchEventPreviewer* pTouchEventPreviewer = control.GetPropagatedTouchEventListener();
794                 SysTryReturn(NID_UI, pTouchEventPreviewer, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
795
796                 r = FirePreviewListener(pTouchEventPreviewer, &control, isFiltered);
797         }
798
799         return r;
800 }
801
802 result
803 _UiMouseEvent::OnEventProcessing(const _Control& control, bool& isFiltered)
804 {
805         result r = E_SUCCESS;
806
807         bool doesControlExist = false;
808
809         const _MouseInfo* pMouseInfo = GetTouchInfo();
810         SysTryReturn(NID_UI, pMouseInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
811
812         if ((!ExistGlobalGesture() || GetAccessibilityEvent()) && !isFiltered)
813         {
814                 ProcessGesture(control, isFiltered);
815         }
816         else if (isFiltered)
817         {
818                 doesControlExist = __pForcedControlList->Contains(const_cast<_Control*>(&control));
819
820                 if (doesControlExist)
821                 {
822                         bool isForcedFiltered = false;
823                         ProcessGesture(control, isForcedFiltered);
824
825                         if (isForcedFiltered)
826                         {
827                                 isFiltered = true;
828                         }
829                 }
830         }
831
832         if (!ExistGlobalGesture() || GetAccessibilityEvent())
833         {
834                 if(!isFiltered || doesControlExist)
835                 {
836                         _ITouchEventListener* pTouchEventListener = control.GetPropagatedTouchEventListener();
837                         SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
838
839                         r = FireListener(pTouchEventListener, &control, true, isFiltered);
840                 }
841         }
842
843         return r;
844 }
845
846 result
847 _UiMouseEvent::OnListenerProcessing(const _IUiEventListener& listener, bool& isFiltered)
848 {
849         _ITouchEventListener* pTouchEventListener = dynamic_cast <_ITouchEventListener*>(const_cast <_IUiEventListener*>(&listener));
850         SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
851
852         return FireListener(pTouchEventListener, null, true, isFiltered);
853 }
854
855 result
856 _UiMouseEvent::OnEventHandled(const _Control& control)
857 {
858         _Control* pTarget = const_cast<_Control*>(GetControl(GetDestination()));
859         SysTryReturn(NID_UI, pTarget, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
860
861         const _MouseInfo* pMouseInfo = GetTouchInfo();
862         SysTryReturn(NID_UI, pMouseInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
863
864         result r = E_SUCCESS;
865
866         switch (pMouseInfo->GetTouchStatus())
867         {
868         case _TOUCH_PRESSED:
869                 pTarget->GetPropagatedTouchEventListener()->OnTouchPressHandled(control);
870                 break;
871
872         case _TOUCH_MOVED:
873                 pTarget->GetPropagatedTouchEventListener()->OnTouchMoveHandled(control);
874                 break;
875
876         case _TOUCH_RELEASED:
877                 pTarget->GetPropagatedTouchEventListener()->OnTouchReleaseHandled(control);
878                 break;
879
880         case _TOUCH_CANCELED:
881                 pTarget->GetPropagatedTouchEventListener()->OnTouchCancelHandled(control);
882                 break;
883
884         default:
885                 r = E_SYSTEM;
886                 break;
887         }
888
889         return r;
890 }
891
892 result
893 _UiMouseEvent::FireListener(const _ITouchEventListener* pListener, const _Control* pControl,  bool isTouchEvent, bool& isFiltered)
894 {
895         _ITouchEventListener* pTouchEventListener = const_cast <_ITouchEventListener*>(pListener);
896         SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
897
898         result r = E_SUCCESS;
899
900         const _MouseInfo* pMouseInfo = GetTouchInfo();
901         SysTryReturn(NID_UI, pMouseInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
902
903         const _Control* pTarget = GetControl(GetOriginalDestination());
904         if (pTarget == null)
905         {
906                 SysLog(NID_UI, "pTarget == null, Call ResetTouchInfo.");
907                 _TouchManager* pTouchManager = _TouchManager::GetInstance();
908                 pTouchManager->ResetTouchInfo();
909
910                 return E_SUCCESS;
911 }
912
913         if (ResetTouchInfo(pTarget, *pMouseInfo) == E_SUCCESS)
914         {
915                 isFiltered = true;
916                 return E_SYSTEM;
917         }
918
919         FloatPoint point(0, 0);
920
921         if (pControl)
922         {
923                 _TouchManager* pTouchManager = _TouchManager::GetInstance();
924                 SysAssert(pTouchManager != null)
925
926                 point = GetRelativePoint(*pControl, pMouseInfo->GetCurrentPosition());
927         }
928         else
929         {
930                 point = GetRelativePoint(*pTarget, pMouseInfo->GetCurrentPosition());
931         }
932
933         _MouseInfo mouseInfo(pMouseInfo->GetPointId(), pMouseInfo->GetTouchStatus(), point, pMouseInfo->GetZAxis(), pMouseInfo->GetButtons(), false, pMouseInfo->GetTimeStamp());
934
935         switch (mouseInfo.GetTouchStatus())
936         {
937         case _TOUCH_PRESSED:
938                 isFiltered = pTouchEventListener->OnMousePressed(*pTarget, mouseInfo);
939                 break;
940
941         case _TOUCH_RELEASED:
942                 isFiltered = pTouchEventListener->OnMouseReleased(*pTarget, mouseInfo);
943                 break;
944
945         case _TOUCH_MOVED:
946                 isFiltered = pTouchEventListener->OnMouseMoved(*pTarget, mouseInfo);
947                 break;
948
949         case _WHEEL_MOVED:
950                 isFiltered = pTouchEventListener->OnMouseWheeled(*pTarget, mouseInfo);
951                 break;
952
953         default:
954                 r = E_SYSTEM;
955         }
956
957         if (isFiltered)
958         {
959                 if (pControl)
960                 {
961                         SysLog(NID_UI, "Event Consumed : isFiltered is True : pControl %x", pControl);
962                         //_UiPrintControl(*pControl, false);
963                 }
964                 SysLog(NID_UI, "Event Consumed : isFiltered is True : pTarget %x", pTarget);
965         }
966
967         return r;
968 }
969
970 result
971 _UiMouseEvent::FirePreviewListener(const _ITouchEventPreviewer* pListener, const _Control* pControl, bool& isFiltered)
972 {
973         _ITouchEventPreviewer* pTouchEventPreviewer = const_cast <_ITouchEventPreviewer*>(pListener);
974         SysTryReturn(NID_UI, pTouchEventPreviewer, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
975
976         result r = E_SUCCESS;
977
978         const _MouseInfo* pMouseInfo = GetTouchInfo();
979         SysTryReturn(NID_UI, pMouseInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
980
981         const _Control* pTarget = GetControl(GetDestination());
982
983         FloatPoint point = GetRelativePoint(*pControl, pMouseInfo->GetCurrentPosition());
984
985         if (!pControl->IsMultiTouchEnabled() && pMouseInfo->GetPointId() > 0)
986         {
987                 isFiltered = false;
988                 return E_SUCCESS;
989         }
990
991         _MouseInfo mouseInfo(pMouseInfo->GetPointId(), pMouseInfo->GetTouchStatus(), point, pMouseInfo->GetZAxis(), pMouseInfo->GetButtons(), false, pMouseInfo->GetTimeStamp());
992
993         _UiTouchEventDelivery eventDelivery = _UI_TOUCH_EVENT_DELIVERY_NO;
994
995         //condition 1) if target is not enabled multi touch, point id should be 0
996         //2) target is enabled multi touch
997         switch (mouseInfo.GetTouchStatus())
998         {
999         case _TOUCH_PRESSED:
1000                 eventDelivery = pTouchEventPreviewer->OnPreviewMousePressed(*pTarget, mouseInfo);
1001                 break;
1002
1003         case _TOUCH_RELEASED:
1004                 eventDelivery = pTouchEventPreviewer->OnPreviewMouseReleased(*pTarget, mouseInfo);
1005                 break;
1006
1007         case _TOUCH_MOVED:
1008                 eventDelivery = pTouchEventPreviewer->OnPreviewMouseMoved(*pTarget, mouseInfo);
1009                 break;
1010
1011         case _WHEEL_MOVED:
1012                 eventDelivery = pTouchEventPreviewer->OnPreviewMouseWheeled(*pTarget, mouseInfo);
1013                 break;
1014
1015         default:
1016                 r = E_SYSTEM;
1017                 break;
1018         }
1019
1020         if (eventDelivery != _UI_TOUCH_EVENT_DELIVERY_NO)
1021         {
1022                 // isFiltered = (eventDelivery == _UI_TOUCH_EVENT_DELIVERY_FORCED_YES);
1023
1024                 // if (isFiltered)
1025                 if (eventDelivery == _UI_TOUCH_EVENT_DELIVERY_FORCED_YES)
1026                 {
1027                         __pForcedControlList->Add(const_cast<_Control*>(pControl));
1028                 }
1029         }
1030         else
1031         {
1032                 isFiltered = true;
1033         }
1034
1035         return r;
1036 }
1037
1038 result
1039 _UiMouseEvent::ProcessGesture(const _Control& control, bool& isFiltered)
1040 {
1041         if (control.IsSendingDelayedEvent())
1042         {
1043                 return E_SUCCESS;
1044         }
1045
1046         IListT<_TouchGestureDetector*>* pGestureList = control.GetGestureDetectorList();
1047         if (!pGestureList || (pGestureList && (pGestureList->GetCount() <= 0)))
1048         {
1049                 return E_SUCCESS;
1050         }
1051
1052         IEnumeratorT<_TouchGestureDetector*>* pEnumerator = pGestureList->GetEnumeratorN();
1053         SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
1054
1055         while (pEnumerator->MoveNext() == E_SUCCESS)
1056         {
1057                 _TouchGestureDetector* pGestureDetector = null;
1058                 pEnumerator->GetCurrent(pGestureDetector);
1059
1060                 if (!pGestureDetector)
1061                 {
1062                         continue;
1063                 }
1064
1065                 _ITouchGestureDelegate* pDelegator = pGestureDetector->GetDelegate();
1066                 if (pDelegator)
1067                 {
1068                         FireListener(pDelegator, &control, false, isFiltered);
1069                 }
1070         }
1071
1072         delete pEnumerator;
1073         return E_SUCCESS;
1074 }
1075
1076 FloatPoint
1077 _UiMouseEvent::GetRelativePoint(const _Control& control, const FloatPoint& point) const
1078 {
1079         FloatPoint relativePoint(point);
1080         FloatRectangle absRect = control.GetAbsoluteBoundsF();
1081
1082         relativePoint.x -= absRect.x;
1083         relativePoint.y -= absRect.y;
1084
1085         return relativePoint;
1086 }
1087
1088 result
1089 _UiMouseEvent::ResetTouchInfo(const _Control* pControl, const _MouseInfo& mouseInfo)
1090 {
1091         _TouchManager* pTouchManager = _TouchManager::GetInstance();
1092         SysTryReturnResult(NID_UI, pTouchManager, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
1093
1094         if (pControl == null)
1095         {
1096                 if (mouseInfo.GetTouchStatus() == _TOUCH_RELEASED)
1097                 {
1098                         pTouchManager->ResetTouchInfo();
1099                 }
1100
1101                 return E_SUCCESS;
1102         }
1103
1104         return E_INVALID_CONDITION;
1105 }
1106
1107 bool
1108 _UiMouseEvent::ExistGlobalGesture(void)
1109 {
1110         _ControlManager* pControlManager = _ControlManager::GetInstance();
1111         SysTryReturn(NID_UI, pControlManager, false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
1112
1113         bool exist = false;
1114
1115         IListT<_TouchGestureDetector*>* pGestureList = pControlManager->GetGestureDetectorList();
1116         if (pGestureList && (pGestureList->GetCount() > 0))
1117         {
1118                 exist = true;
1119         }
1120
1121         return exist;
1122 }
1123
1124 }} // Tizen::Ui