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 (!control.IsInputEventEnabled())
221 _UiTouchEvent::OnPreviewEventProcessing(const _Control& control, bool& isFiltered)
223 result r = E_SUCCESS;
225 const _TouchInfo* pTouchInfo = GetTouchInfo();
226 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
228 if ((!ExistGlobalGesture() || GetAccessibilityEvent()) && !isFiltered)
230 _ITouchEventPreviewer* pTouchEventPreviewer = control.GetPropagatedTouchEventListener();
231 SysTryReturn(NID_UI, pTouchEventPreviewer, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
233 r = FirePreviewListener(pTouchEventPreviewer, &control, isFiltered);
240 _UiTouchEvent::OnEventProcessing(const _Control& control, bool& isFiltered)
242 result r = E_SUCCESS;
244 bool doesControlExist = false;
246 const _TouchInfo* pTouchInfo = GetTouchInfo();
247 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
249 if ((!ExistGlobalGesture() || GetAccessibilityEvent()) && !isFiltered)
251 ProcessGesture(control, isFiltered);
255 doesControlExist = __pForcedControlList->Contains(const_cast<_Control*>(&control));
257 if (doesControlExist)
259 bool isForcedFiltered = false;
260 ProcessGesture(control, isForcedFiltered);
262 if (isForcedFiltered)
269 if (!ExistGlobalGesture() || GetAccessibilityEvent())
271 if(!isFiltered || doesControlExist)
273 _ITouchEventListener* pTouchEventListener = control.GetPropagatedTouchEventListener();
274 SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
276 r = FireListener(pTouchEventListener, &control, true, isFiltered);
284 _UiTouchEvent::OnListenerProcessing(const _IUiEventListener& listener, bool& isFiltered)
286 _ITouchEventListener* pTouchEventListener = dynamic_cast <_ITouchEventListener*>(const_cast <_IUiEventListener*>(&listener));
287 SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
289 return FireListener(pTouchEventListener, null, true, isFiltered);
293 _UiTouchEvent::OnEventHandled(const _Control& control)
295 _Control* pTarget = const_cast<_Control*>(GetControl(GetDestination()));
296 SysTryReturn(NID_UI, pTarget, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
298 const _TouchInfo* pTouchInfo = GetTouchInfo();
299 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
301 result r = E_SUCCESS;
303 switch (pTouchInfo->GetTouchStatus())
306 pTarget->GetPropagatedTouchEventListener()->OnTouchPressHandled(control);
310 pTarget->GetPropagatedTouchEventListener()->OnTouchMoveHandled(control);
313 case _TOUCH_RELEASED:
314 pTarget->GetPropagatedTouchEventListener()->OnTouchReleaseHandled(control);
317 case _TOUCH_CANCELED:
318 pTarget->GetPropagatedTouchEventListener()->OnTouchCancelHandled(control);
330 _UiTouchEvent::FireListener(const _ITouchEventListener* pListener, const _Control* pControl, bool isTouchEvent, bool& isFiltered)
332 _ITouchEventListener* pTouchEventListener = const_cast <_ITouchEventListener*>(pListener);
333 SysTryReturn(NID_UI, pTouchEventListener, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
335 result r = E_SUCCESS;
337 const _TouchInfo* pTouchInfo = GetTouchInfo();
338 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
340 const _Control* pTarget = GetControl(GetOriginalDestination());
343 SysLog(NID_UI, "pTarget == null, Call ResetTouchInfo.");
344 _TouchManager* pTouchManager = _TouchManager::GetInstance();
345 pTouchManager->ResetTouchInfo();
351 if (ResetTouchInfo(pTarget, *pTouchInfo) == E_SUCCESS)
357 FloatPoint point(0, 0);
361 _TouchManager* pTouchManager = _TouchManager::GetInstance();
362 SysAssert(pTouchManager != null)
364 point = GetRelativePoint(*pControl, pTouchInfo->GetCurrentPosition());
366 if (isTouchEvent && (pTouchInfo->GetTouchStatus() != _TOUCH_CANCELED))
368 if (!pTouchManager->IsTouchAllowed() || (pTouchManager->IsTouchAllowed() && pTouchManager->IsTouchCanceledOnGestureSuccess())
369 || (!pControl->IsMultiTouchEnabled() && pTouchInfo->GetPointId() > 0))
378 point = GetRelativePoint(*pTarget, pTouchInfo->GetCurrentPosition());
381 _TouchInfo touchInfo(pTouchInfo->GetPointId(), pTouchInfo->GetTouchStatus(), point, false, pTouchInfo->GetTimeStamp());
383 switch (touchInfo.GetTouchStatus())
386 isFiltered = pTouchEventListener->OnTouchPressed(*pTarget, touchInfo);
389 case _TOUCH_RELEASED:
390 isFiltered = pTouchEventListener->OnTouchReleased(*pTarget, touchInfo);
394 isFiltered = pTouchEventListener->OnTouchMoved(*pTarget, touchInfo);
397 // 2.0 compatibility for touch simulate
398 case _TOUCH_LONG_PRESSED:
400 case _TOUCH_DOUBLE_PRESSED:
402 void* pData = pTarget->GetUserData();
405 _ControlImpl* pTargetImpl = static_cast<_ControlImpl*>(pData);
408 pTargetImpl->GenerateTouchEvent(touchInfo);
414 case _TOUCH_CANCELED:
415 isFiltered = pTouchEventListener->OnTouchCanceled(*pTarget, touchInfo);
426 SysLog(NID_UI, "Event Consumed : isFiltered is True : pControl %x", pControl);
427 //_UiPrintControl(*pControl, false);
429 SysLog(NID_UI, "Event Consumed : isFiltered is True : pTarget %x", pTarget);
436 _UiTouchEvent::FirePreviewListener(const _ITouchEventPreviewer* pListener, const _Control* pControl, bool& isFiltered)
438 _ITouchEventPreviewer* pTouchEventPreviewer = const_cast <_ITouchEventPreviewer*>(pListener);
439 SysTryReturn(NID_UI, pTouchEventPreviewer, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
441 result r = E_SUCCESS;
443 const _TouchInfo* pTouchInfo = GetTouchInfo();
444 SysTryReturn(NID_UI, pTouchInfo, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
446 const _Control* pTarget = GetControl(GetDestination());
448 FloatPoint point = GetRelativePoint(*pControl, pTouchInfo->GetCurrentPosition());
450 if (!pControl->IsMultiTouchEnabled() && pTouchInfo->GetPointId() > 0)
456 _TouchInfo touchInfo(pTouchInfo->GetPointId(), pTouchInfo->GetTouchStatus(), point, false, pTouchInfo->GetTimeStamp());
458 _UiTouchEventDelivery eventDelivery = _UI_TOUCH_EVENT_DELIVERY_NO;
460 //condition 1) if target is not enabled multi touch, point id should be 0
461 //2) target is enabled multi touch
462 switch (touchInfo.GetTouchStatus())
465 eventDelivery = pTouchEventPreviewer->OnPreviewTouchPressed(*pTarget, touchInfo);
469 case _TOUCH_RELEASED:
470 eventDelivery = pTouchEventPreviewer->OnPreviewTouchReleased(*pTarget, touchInfo);
475 eventDelivery = pTouchEventPreviewer->OnPreviewTouchMoved(*pTarget, touchInfo);
479 case _TOUCH_CANCELED:
480 eventDelivery = pTouchEventPreviewer->OnPreviewTouchCanceled(*pTarget, touchInfo);
488 if (eventDelivery != _UI_TOUCH_EVENT_DELIVERY_NO)
490 // isFiltered = (eventDelivery == _UI_TOUCH_EVENT_DELIVERY_FORCED_YES);
493 if (eventDelivery == _UI_TOUCH_EVENT_DELIVERY_FORCED_YES)
495 __pForcedControlList->Add(const_cast<_Control*>(pControl));
507 _UiTouchEvent::ProcessGesture(const _Control& control, bool& isFiltered)
509 if (control.IsSendingDelayedEvent())
514 IListT<_TouchGestureDetector*>* pGestureList = control.GetGestureDetectorList();
515 if (!pGestureList || (pGestureList && (pGestureList->GetCount() <= 0)))
520 IEnumeratorT<_TouchGestureDetector*>* pEnumerator = pGestureList->GetEnumeratorN();
521 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
523 while (pEnumerator->MoveNext() == E_SUCCESS)
525 _TouchGestureDetector* pGestureDetector = null;
526 pEnumerator->GetCurrent(pGestureDetector);
528 if (!pGestureDetector)
533 _ITouchGestureDelegate* pDelegator = pGestureDetector->GetDelegate();
536 FireListener(pDelegator, &control, false, isFiltered);
545 _UiTouchEvent::GetRelativePoint(const _Control& control, const FloatPoint& point) const
547 FloatPoint relativePoint(point);
548 FloatRectangle absRect = control.GetAbsoluteBoundsF();
550 relativePoint.x -= absRect.x;
551 relativePoint.y -= absRect.y;
553 return relativePoint;
557 _UiTouchEvent::ResetTouchInfo(const _Control* pControl, const _TouchInfo& touchInfo)
559 _TouchManager* pTouchManager = _TouchManager::GetInstance();
560 SysTryReturnResult(NID_UI, pTouchManager, E_SYSTEM, "[E_SYSTEM] System error occurred. ");
562 if (pControl == null)
564 if (touchInfo.GetTouchStatus() == _TOUCH_RELEASED)
566 pTouchManager->ResetTouchInfo();
572 return E_INVALID_CONDITION;
576 _UiTouchEvent::ExistGlobalGesture(void)
578 _ControlManager* pControlManager = _ControlManager::GetInstance();
579 SysTryReturn(NID_UI, pControlManager, false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
583 IListT<_TouchGestureDetector*>* pGestureList = pControlManager->GetGestureDetectorList();
584 if (pGestureList && (pGestureList->GetCount() > 0))