2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0/
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an ”AS IS” BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 * @file FUi_UiTouchEvent.cpp
19 * @brief This is the implementation file for the _UiTouchEvent class.
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"
39 extern void _UiPrintControl(const Tizen::Ui::_Control& control, bool printChildren);
43 using namespace std::tr1;
44 using namespace Tizen::Base::Collection;
45 using namespace Tizen::Graphics;
47 namespace Tizen { namespace Ui
49 _TouchInfo::_TouchInfo(void)
51 , __touchStatus(_TOUCH_PRESSED)
52 , __currentPosition(0, 0)
58 _TouchInfo::_TouchInfo(unsigned long pointId, _TouchStatus status, const Tizen::Graphics::Point& current, const bool isFlick, long long timeStamp)
60 , __touchStatus(status)
61 , __isFlicked(isFlick)
62 , __timeStamp(timeStamp)
64 __currentPosition = _CoordinateSystemUtils::ConvertToFloat(current);
67 _TouchInfo::_TouchInfo(unsigned long pointId, _TouchStatus status, const Tizen::Graphics::FloatPoint& current, const bool isFlick, long long timeStamp)
69 , __touchStatus(status)
70 , __currentPosition(current)
71 , __isFlicked(isFlick)
72 , __timeStamp(timeStamp)
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)
86 _TouchInfo::operator =(const _TouchInfo& rhs)
90 __pointId = rhs.__pointId;
91 __touchStatus = rhs.__touchStatus;
92 __currentPosition = rhs.__currentPosition;
93 __isFlicked = rhs.__isFlicked;
94 __timeStamp = rhs.__timeStamp;
100 _TouchInfo::~_TouchInfo(void)
105 _TouchInfo::GetTouchStatus(void) const
107 return __touchStatus;
110 Tizen::Graphics::FloatPoint
111 _TouchInfo::GetCurrentPosition(void) const
113 return __currentPosition;
117 _TouchInfo::GetPointId(void) const
123 _TouchInfo::IsFlicked(void) const
129 _TouchInfo::GetTimeStamp(void) const
135 _TouchInfo::SetTouchInfo(unsigned long pointId, _TouchStatus status, Tizen::Graphics::Point& current, bool isFlick, long long timeStamp)
138 __touchStatus = status;
139 __currentPosition = _CoordinateSystemUtils::ConvertToFloat(current);
140 __isFlicked = isFlick;
141 __timeStamp = timeStamp;
145 _TouchInfo::SetTouchInfo(unsigned long pointId, _TouchStatus status, Tizen::Graphics::FloatPoint& current, bool isFlick, long long timeStamp)
148 __touchStatus = status;
149 __currentPosition = current;
150 __isFlicked = isFlick;
151 __timeStamp = timeStamp;
154 _UiTouchEvent::_UiTouchEvent(const _UiObjectHandle& destination, const _TouchInfo& touchInfo, _UiEventRouteType routeType, const _UiObjectHandle& source)
155 : _UiEvent(destination, source, routeType)
156 , __touchInfo(touchInfo)
157 , __pForcedControlList(new (std::nothrow) LinkedListT<_Control*>)
161 _UiTouchEvent::~_UiTouchEvent(void)
165 _UiTouchEvent::_UiTouchEvent(const _UiTouchEvent& rhs)
167 , __touchInfo(rhs.__touchInfo)
168 , __pForcedControlList(rhs.__pForcedControlList)
173 _UiTouchEvent::operator =(const _UiTouchEvent& rhs)
175 _UiEvent::operator =(rhs);
179 __touchInfo = rhs.__touchInfo;
180 __pForcedControlList = rhs.__pForcedControlList;
187 _UiTouchEvent::GetTouchInfo(void) const
193 _UiTouchEvent::CloneN(void) const
195 return new (std::nothrow) _UiTouchEvent(*this);
199 _UiTouchEvent::GetEventType(void) const
201 return _UI_EVENT_TOUCH;
205 _UiTouchEvent::IsEventEnabled(const _Control& control) const
207 if (!_UiEvent::IsEventEnabled(control))
212 if (GetTouchInfo()->GetTouchStatus() != _TOUCH_CANCELED)
214 if (!control.IsInputEventEnabled())
224 _UiTouchEvent::OnPreviewEventProcessing(const _Control& control, bool& isFiltered)
226 result r = E_SUCCESS;
228 const _TouchInfo* pTouchInfo = GetTouchInfo();
229 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
231 if ((!ExistGlobalGesture() || GetAccessibilityEvent()) && !isFiltered)
233 _ITouchEventPreviewer* pTouchEventPreviewer = control.GetPropagatedTouchEventListener();
234 SysTryReturn(NID_UI, pTouchEventPreviewer, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
236 r = FirePreviewListener(pTouchEventPreviewer, &control, isFiltered);
243 _UiTouchEvent::OnEventProcessing(const _Control& control, bool& isFiltered)
245 result r = E_SUCCESS;
247 bool doesControlExist = false;
249 const _TouchInfo* pTouchInfo = GetTouchInfo();
250 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
252 if ((!ExistGlobalGesture() || GetAccessibilityEvent()) && !isFiltered)
254 ProcessGesture(control, isFiltered);
258 doesControlExist = __pForcedControlList->Contains(const_cast<_Control*>(&control));
260 if (doesControlExist)
262 bool isForcedFiltered = false;
263 ProcessGesture(control, isForcedFiltered);
265 if (isForcedFiltered)
272 if (!ExistGlobalGesture() || GetAccessibilityEvent())
274 if(!isFiltered || doesControlExist)
276 _ITouchEventListener* pTouchEventListener = control.GetPropagatedTouchEventListener();
277 SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
279 r = FireListener(pTouchEventListener, &control, true, isFiltered);
287 _UiTouchEvent::OnListenerProcessing(const _IUiEventListener& listener, bool& isFiltered)
289 _ITouchEventListener* pTouchEventListener = dynamic_cast <_ITouchEventListener*>(const_cast <_IUiEventListener*>(&listener));
290 SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
292 return FireListener(pTouchEventListener, null, true, isFiltered);
296 _UiTouchEvent::OnEventHandled(const _Control& control)
298 _Control* pTarget = const_cast<_Control*>(GetControl(GetDestination()));
299 SysTryReturn(NID_UI, pTarget, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
301 const _TouchInfo* pTouchInfo = GetTouchInfo();
302 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
304 result r = E_SUCCESS;
306 switch (pTouchInfo->GetTouchStatus())
309 pTarget->GetPropagatedTouchEventListener()->OnTouchPressHandled(control);
313 pTarget->GetPropagatedTouchEventListener()->OnTouchMoveHandled(control);
316 case _TOUCH_RELEASED:
317 pTarget->GetPropagatedTouchEventListener()->OnTouchReleaseHandled(control);
320 case _TOUCH_CANCELED:
321 pTarget->GetPropagatedTouchEventListener()->OnTouchCancelHandled(control);
333 _UiTouchEvent::FireListener(const _ITouchEventListener* pListener, const _Control* pControl, bool isTouchEvent, bool& isFiltered)
335 _ITouchEventListener* pTouchEventListener = const_cast <_ITouchEventListener*>(pListener);
336 SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
338 result r = E_SUCCESS;
340 const _TouchInfo* pTouchInfo = GetTouchInfo();
341 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
343 const _Control* pTarget = GetControl(GetOriginalDestination());
346 SysLog(NID_UI, "pTarget == null, Call ResetTouchInfo.");
347 _TouchManager* pTouchManager = _TouchManager::GetInstance();
348 pTouchManager->ResetTouchInfo();
354 if (ResetTouchInfo(pTarget, *pTouchInfo) == E_SUCCESS)
360 FloatPoint point(0, 0);
364 _TouchManager* pTouchManager = _TouchManager::GetInstance();
365 SysAssert(pTouchManager != null)
367 point = GetRelativePoint(*pControl, pTouchInfo->GetCurrentPosition());
369 if (isTouchEvent && (pTouchInfo->GetTouchStatus() != _TOUCH_CANCELED))
371 if (!pTouchManager->IsTouchAllowed() || (pTouchManager->IsTouchAllowed() && pTouchManager->IsTouchCanceledOnGestureSuccess())
372 || (!pControl->IsMultiTouchEnabled() && pTouchInfo->GetPointId() > 0))
381 point = GetRelativePoint(*pTarget, pTouchInfo->GetCurrentPosition());
384 _TouchInfo touchInfo(pTouchInfo->GetPointId(), pTouchInfo->GetTouchStatus(), point, false, pTouchInfo->GetTimeStamp());
386 switch (touchInfo.GetTouchStatus())
389 isFiltered = pTouchEventListener->OnTouchPressed(*pTarget, touchInfo);
392 case _TOUCH_RELEASED:
393 isFiltered = pTouchEventListener->OnTouchReleased(*pTarget, touchInfo);
397 isFiltered = pTouchEventListener->OnTouchMoved(*pTarget, touchInfo);
400 // 2.0 compatibility for touch simulate
401 case _TOUCH_LONG_PRESSED:
403 case _TOUCH_DOUBLE_PRESSED:
405 void* pData = pTarget->GetUserData();
408 _ControlImpl* pTargetImpl = static_cast<_ControlImpl*>(pData);
411 pTargetImpl->GenerateTouchEvent(touchInfo);
417 case _TOUCH_CANCELED:
418 isFiltered = pTouchEventListener->OnTouchCanceled(*pTarget, touchInfo);
429 SysLog(NID_UI, "Event Consumed : isFiltered is True : pControl %x", pControl);
430 //_UiPrintControl(*pControl, false);
432 SysLog(NID_UI, "Event Consumed : isFiltered is True : pTarget %x", pTarget);
439 _UiTouchEvent::FirePreviewListener(const _ITouchEventPreviewer* pListener, const _Control* pControl, bool& isFiltered)
441 _ITouchEventPreviewer* pTouchEventPreviewer = const_cast <_ITouchEventPreviewer*>(pListener);
442 SysTryReturn(NID_UI, pTouchEventPreviewer, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
444 result r = E_SUCCESS;
446 const _TouchInfo* pTouchInfo = GetTouchInfo();
447 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
449 const _Control* pTarget = GetControl(GetDestination());
451 FloatPoint point = GetRelativePoint(*pControl, pTouchInfo->GetCurrentPosition());
453 if (!pControl->IsMultiTouchEnabled() && pTouchInfo->GetPointId() > 0)
459 _TouchInfo touchInfo(pTouchInfo->GetPointId(), pTouchInfo->GetTouchStatus(), point, false, pTouchInfo->GetTimeStamp());
461 _UiTouchEventDelivery eventDelivery = _UI_TOUCH_EVENT_DELIVERY_NO;
463 //condition 1) if target is not enabled multi touch, point id should be 0
464 //2) target is enabled multi touch
465 switch (touchInfo.GetTouchStatus())
468 eventDelivery = pTouchEventPreviewer->OnPreviewTouchPressed(*pTarget, touchInfo);
472 case _TOUCH_RELEASED:
473 eventDelivery = pTouchEventPreviewer->OnPreviewTouchReleased(*pTarget, touchInfo);
478 eventDelivery = pTouchEventPreviewer->OnPreviewTouchMoved(*pTarget, touchInfo);
482 case _TOUCH_CANCELED:
483 eventDelivery = pTouchEventPreviewer->OnPreviewTouchCanceled(*pTarget, touchInfo);
491 if (eventDelivery != _UI_TOUCH_EVENT_DELIVERY_NO)
493 // isFiltered = (eventDelivery == _UI_TOUCH_EVENT_DELIVERY_FORCED_YES);
496 if (eventDelivery == _UI_TOUCH_EVENT_DELIVERY_FORCED_YES)
498 __pForcedControlList->Add(const_cast<_Control*>(pControl));
510 _UiTouchEvent::ProcessGesture(const _Control& control, bool& isFiltered)
512 if (control.IsSendingDelayedEvent())
517 IListT<_TouchGestureDetector*>* pGestureList = control.GetGestureDetectorList();
518 if (!pGestureList || (pGestureList && (pGestureList->GetCount() <= 0)))
523 IEnumeratorT<_TouchGestureDetector*>* pEnumerator = pGestureList->GetEnumeratorN();
524 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
526 while (pEnumerator->MoveNext() == E_SUCCESS)
528 _TouchGestureDetector* pGestureDetector = null;
529 pEnumerator->GetCurrent(pGestureDetector);
531 if (!pGestureDetector)
536 _ITouchGestureDelegate* pDelegator = pGestureDetector->GetDelegate();
539 FireListener(pDelegator, &control, false, isFiltered);
548 _UiTouchEvent::GetRelativePoint(const _Control& control, const FloatPoint& point) const
550 FloatPoint relativePoint(point);
551 FloatRectangle absRect = control.GetAbsoluteBoundsF();
553 relativePoint.x -= absRect.x;
554 relativePoint.y -= absRect.y;
556 return relativePoint;
560 _UiTouchEvent::ResetTouchInfo(const _Control* pControl, const _TouchInfo& touchInfo)
562 _TouchManager* pTouchManager = _TouchManager::GetInstance();
563 SysTryReturnResult(NID_UI, pTouchManager, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
565 if (pControl == null)
567 if (touchInfo.GetTouchStatus() == _TOUCH_RELEASED)
569 pTouchManager->ResetTouchInfo();
575 return E_INVALID_CONDITION;
579 _UiTouchEvent::ExistGlobalGesture(void)
581 _ControlManager* pControlManager = _ControlManager::GetInstance();
582 SysTryReturn(NID_UI, pControlManager, false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
586 IListT<_TouchGestureDetector*>* pGestureList = pControlManager->GetGestureDetectorList();
587 if (pGestureList && (pGestureList->GetCount() > 0))