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_UiEventManager.cpp
19 * @brief This is the implementation file for the _UiEventManager class.
23 #include <FBaseColHashMapT.h>
24 #include <FBaseColIMapEnumeratorT.h>
25 #include <FBaseColLinkedListT.h>
26 #include <FBaseSysLog.h>
27 #include "FUi_UiEventManager.h"
28 #include "FUi_UiEvent.h"
29 #include "FUi_INotificationEventListener.h"
30 #include "FUi_IKeyEventListener.h"
31 #include "FUi_ITouchEventListener.h"
32 #include "FUi_IFocusEventListener.h"
33 #include "FUi_EflUiEventManager.h"
34 #include "FUi_Control.h"
35 #include "FUi_ControlManager.h"
36 #include "FUi_TouchManager.h"
37 #include "FUi_TouchGestureDetector.h"
38 #include "FUiAnim_ControlVisualElement.h"
39 #include "FUi_UiKeyEvent.h"
40 #include "FUi_KeyEventManager.h"
41 #include "FUi_ResourceManager.h"
42 #include "FUi_Window.h"
45 using namespace Tizen::Base;
46 using namespace Tizen::Base::Collection;
47 using namespace Tizen::Graphics;
48 using namespace Tizen::Ui::Animations;
50 namespace Tizen { namespace Ui
53 _UiEventManager* _UiEventManager::__pInstance = null;
56 _UiEventManager::Initialize(void)
58 static pthread_once_t once_block = PTHREAD_ONCE_INIT;
62 pthread_once(&once_block, InitInstance);
67 _UiEventManager::Release(void)
74 _UiEventManager::GetInstance(void)
80 _UiEventManager::InitInstance(void)
84 __pInstance = new (std::nothrow) _UiEventManager;
85 SysAssert(__pInstance);
90 _UiEventManager::AddTouchEventListener(const _ITouchEventListener& listener)
92 return AddEventListener(_UI_EVENT_TOUCH, false, listener);
96 _UiEventManager::AddKeyEventListener(const _IKeyEventListener& listener)
98 return AddEventListener(_UI_EVENT_KEY, false, listener);
102 _UiEventManager::AddFocusEventListener(const _IFocusEventListener& listener)
104 return AddEventListener(_UI_EVENT_FOCUS, false, listener);
108 _UiEventManager::AddNotificationEventListener(const _INotificationEventListener& listener)
110 return AddEventListener(_UI_EVENT_NOTIFICAITON, false, listener);
114 _UiEventManager::RemoveTouchEventListener(const _ITouchEventListener& listener)
116 return RemoveEventListener(_UI_EVENT_TOUCH, false, listener);
120 _UiEventManager::RemoveKeyEventListener(const _IKeyEventListener& listener)
122 return RemoveEventListener(_UI_EVENT_KEY, false, listener);
126 _UiEventManager::RemoveFocusEventListener(const _IFocusEventListener& listener)
128 return RemoveEventListener(_UI_EVENT_FOCUS, false, listener);
132 _UiEventManager::RemoveNotificationEventListener(const _INotificationEventListener& listener)
134 return RemoveEventListener(_UI_EVENT_NOTIFICAITON, false, listener);
138 _UiEventManager::AddPostKeyEventListener(const _IKeyEventListener& listener)
140 return AddEventListener(_UI_EVENT_KEY, true, listener);
144 _UiEventManager::RemovePostKeyEventListener(const _IKeyEventListener& listener)
146 return RemoveEventListener(_UI_EVENT_KEY, true, listener);
150 _UiEventManager::SendEvent(const _UiEvent& event)
152 result r = E_SUCCESS;
160 _UiEventManager::PostEvent(const _UiEvent& event)
162 return __pEventManager->PostEvent(event);
166 _UiEventManager::GenerateKeyEvent(KeyState keyState, _KeyCode keyCode, _KeyModifier keyModifier, bool async)
168 result r = E_SUCCESS;
170 _UiObjectHandle uiObjectHandle = GetTarget();
171 if (uiObjectHandle.IsNull())
176 _UiEventRouteType routeType = (keyState == KEY_LONGPRESSED) ? _UI_EVENT_ROUTE_DIRECT : _UI_EVENT_ROUTE_TUNNEL_BUBBLE;
178 _KeyInfo keyInfo(keyState, keyCode, keyModifier, null);
180 _UiKeyEvent event(uiObjectHandle, keyInfo, routeType);
184 r = PostEvent(event);
188 r = SendEvent(event);
191 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
197 _UiEventManager::GenerateTouchEvent(_TouchStatus touchStatus, int x, int y, bool async)
199 result r = E_SUCCESS;
201 _UiObjectHandle uiObjectHandle = GetTarget(x, y);
202 if (uiObjectHandle.IsNull())
207 const unsigned long DEVICE_ID = 0;
210 unsigned int pointId = 0;
211 _UiEventRouteType routeType = _UI_EVENT_ROUTE_TUNNEL_BUBBLE;
213 _TouchManager* pTouchManager = _TouchManager::GetInstance();
214 SysTryReturn(NID_UI, pTouchManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
219 pointId = pTouchManager->GeneratePointId(DEVICE_ID);
222 case _TOUCH_LONG_PRESSED:
224 case _TOUCH_DOUBLE_PRESSED:
225 routeType = _UI_EVENT_ROUTE_DIRECT;
226 pointId = pTouchManager->GetPointId(DEVICE_ID);
230 pointId = pTouchManager->GetPointId(DEVICE_ID);
234 _TouchInfo touchInfo(pointId, touchStatus, current, false, 0);
235 _UiTouchEvent event(uiObjectHandle, touchInfo, routeType);
239 r = PostEvent(event);
243 r = SendEvent(event);
246 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
252 _UiEventManager::GetEventManager(void) const
254 return __pEventManager.get();
258 _UiEventManager::AddEventListener(_UiEventType eventType, bool postListener, const _IUiEventListener& listener)
260 result r = E_SUCCESS;
262 SysTryReturn(NID_UI, !IsListenerRegistered(eventType, postListener, listener), E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
264 LinkedListT <_IUiEventListener*>* pEventListeners = GetEventListeners(eventType, postListener);
267 pEventListeners->Add(const_cast <_IUiEventListener*>(&listener));
274 _UiEventManager::RemoveEventListener(_UiEventType eventType, bool postListener, const _IUiEventListener& listener)
276 result r = E_SUCCESS;
278 LinkedListT <_IUiEventListener*>* pEventListeners = GetEventListeners(eventType, postListener);
281 pEventListeners->Remove(const_cast <_IUiEventListener*>(&listener));
288 _UiEventManager::IsListenerRegistered(_UiEventType eventType, bool postListener, const _IUiEventListener& listener)
290 bool isRegistered = false;
292 LinkedListT <_IUiEventListener*>* pEventListeners = GetEventListeners(eventType, postListener);
295 Tizen::Base::Collection::IEnumeratorT <_IUiEventListener*>* pEnumerator = pEventListeners->GetEnumeratorN();
296 SysTryReturn(NID_UI, pEnumerator, false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
298 while (pEnumerator->MoveNext() == E_SUCCESS)
300 _IUiEventListener* pEventListener = null;
301 pEnumerator->GetCurrent(pEventListener);
307 if (pEventListener == &listener)
321 _UiEventManager::Fire(const _UiEvent& event)
323 result r = E_SUCCESS;
325 bool isFiltered = false;
327 r = ProcessListener(event, isFiltered);
328 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
332 r = ProcessGlobalGesture(event, isFiltered);
333 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
336 if (event.GetEventType() == _UI_EVENT_TOUCH)
338 r = ProcessEvent(event, isFiltered);
339 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
341 else if (!isFiltered)
343 r = ProcessEvent(event, isFiltered);
344 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
350 LinkedListT <_IUiEventListener*>*
351 _UiEventManager::GetEventListeners(_UiEventType eventType, bool postListener) const
353 LinkedListT <_IUiEventListener*>* pEventListeners = null;
357 __pPostEventListenerMap->GetValue(eventType, pEventListeners);
361 result r = E_SUCCESS;
363 r = __pEventListenerMap->GetValue(eventType, pEventListeners);
364 SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
367 return pEventListeners;
371 _UiEventManager::ProcessListener(const _UiEvent& event, bool& isFiltered)
373 return ProcessListener(event, false, isFiltered);
377 _UiEventManager::ProcessPostListener(const _UiEvent& event, bool& isFiltered)
379 return ProcessListener(event, true, isFiltered);
383 _UiEventManager::ProcessListener(const _UiEvent& event, bool postListener, bool& isFiltered)
385 result r = E_SUCCESS;
387 LinkedListT <_IUiEventListener*>* pEventListeners = GetEventListeners(event.GetEventType(), postListener);
390 Tizen::Base::Collection::IEnumeratorT <_IUiEventListener*>* pEnumerator = pEventListeners->GetEnumeratorN();
391 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
393 while (pEnumerator->MoveNext() == E_SUCCESS)
395 _IUiEventListener* pEventListener = null;
397 pEnumerator->GetCurrent(pEventListener);
403 r = const_cast<_UiEvent&>(event).ProcessListener(*pEventListener, isFiltered);
417 _UiEventManager::ProcessEvent(const _UiEvent& event, bool& isFiltered)
419 result r = E_SUCCESS;
420 _ResourceManager::GetInstance()->AcquireFeedback();
421 switch (event.GetRouteType())
423 case _UI_EVENT_ROUTE_TUNNEL_BUBBLE:
425 LinkedListT <_UiObjectHandle> tunnelingPath;
426 LinkedListT <_UiObjectHandle> bubblingPath;
428 r = MakeRoutingPath(tunnelingPath, bubblingPath, event);
432 ProcessTunnelingEvent(tunnelingPath, event, isFiltered);
434 if (event.GetEventType() == _UI_EVENT_TOUCH)
436 ProcessBubblingEvent(bubblingPath, event, isFiltered);
438 else if (!isFiltered)
440 ProcessBubblingEvent(bubblingPath, event, isFiltered);
446 case _UI_EVENT_ROUTE_DIRECT:
448 _ControlManager* pControlManager = _ControlManager::GetInstance();
449 SysTryReturn(NID_UI, pControlManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
451 const _Control* pTarget = pControlManager->GetObject(event.GetDestination());
454 r = const_cast<_UiEvent&>(event).ProcessEvent(*pTarget, isFiltered);
462 _ResourceManager::GetInstance()->ReleaseFeedback();
467 _UiEventManager::ProcessGlobalGesture(const _UiEvent& event, bool& isFiltered)
469 if (event.GetEventType() != _UI_EVENT_TOUCH)
474 if (event.GetAccessibilityEvent())
479 _ControlManager* pControlManager = _ControlManager::GetInstance();
480 SysTryReturn(NID_UI, pControlManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
482 _TouchManager* pTouchManager = _TouchManager::GetInstance();
483 SysTryReturn(NID_UI, pTouchManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
485 Tizen::Base::Collection::IListT<_TouchGestureDetector*>* pGestureList = pControlManager->GetGestureDetectorList();
486 if (!pGestureList || (pGestureList && (pGestureList->GetCount() <= 0)))
491 result r = E_SUCCESS;
493 Tizen::Base::Collection::IEnumeratorT <_TouchGestureDetector*>* pEnumerator = pGestureList->GetEnumeratorN();
494 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
496 _TouchGestureDetector* pGestureDetector = null;
497 while (pEnumerator->MoveNext() == E_SUCCESS)
499 pEnumerator->GetCurrent(pGestureDetector);
501 if (!pGestureDetector)
506 r = const_cast<_UiEvent&>(event).ProcessListener(*pGestureDetector, isFiltered);
519 _UiEventManager::MakeRoutingPath(Tizen::Base::Collection::LinkedListT <_UiObjectHandle>& tunnelingPath, Tizen::Base::Collection::LinkedListT <_UiObjectHandle>& bubblingPath, const _UiEvent& event)
521 result r = E_SUCCESS;
523 _ControlManager* pControlManager = _ControlManager::GetInstance();
524 SysTryReturn(NID_UI, pControlManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
526 _Control* pControl = pControlManager->GetObject(event.GetDestination());
527 SysTryReturn(NID_UI, pControl, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
530 _Control* pBubblingTarget = pControl;
531 while (pBubblingTarget)
533 bubblingPath.Add(pBubblingTarget->GetHandle());
534 pBubblingTarget = pBubblingTarget->GetParent();
538 for (int i = bubblingPath.GetCount() - 1; i > 0; i--)
540 _UiObjectHandle uiObjectHandle;
542 r = bubblingPath.GetAt(i, uiObjectHandle);
545 tunnelingPath.Add(uiObjectHandle);
553 _UiEventManager::ProcessTunnelingEvent(const Tizen::Base::Collection::LinkedListT <_UiObjectHandle>& routingPath, const _UiEvent& event, bool& isFiltered)
555 result r = E_SUCCESS;
557 Tizen::Base::Collection::IEnumeratorT <_UiObjectHandle>* pEnumerator = routingPath.GetEnumeratorN();
558 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
560 _UiObjectHandle uiObjectHandle;
561 while (pEnumerator->MoveNext() == E_SUCCESS)
563 pEnumerator->GetCurrent(uiObjectHandle);
564 if (uiObjectHandle.IsNull())
569 const _Control* pControl = event.GetControl(uiObjectHandle);
575 r = const_cast<_UiEvent&>(event).ProcessPreviewEvent(*pControl, isFiltered);
589 _UiEventManager::ProcessBubblingEvent(const Tizen::Base::Collection::LinkedListT <_UiObjectHandle>& routingPath, const _UiEvent& event, bool& isFiltered)
591 result r = E_SUCCESS;
593 Tizen::Base::Collection::IEnumeratorT <_UiObjectHandle>* pEnumerator = routingPath.GetEnumeratorN();
594 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
596 _UiObjectHandle uiObjectHandle;
597 while (pEnumerator->MoveNext() == E_SUCCESS)
599 pEnumerator->GetCurrent(uiObjectHandle);
600 if (uiObjectHandle.IsNull())
605 const _Control* pControl = event.GetControl(uiObjectHandle);
611 r = const_cast<_UiEvent&>(event).ProcessEvent(*pControl, isFiltered);
613 if (!isFiltered && (event.GetDestination() == uiObjectHandle))
615 ProcessPostListener(event, isFiltered);
625 _UiEventManager::GetTarget(void) const
627 _Control* pControl = _ControlManager::GetInstance()->GetFocusedControl();
628 SysTryReturn(NID_UI, pControl, _UiObjectHandle(), E_SYSTEM, "[E_SYSTEM] System error occurred.");
630 return pControl->GetHandle();
634 _UiEventManager::GetTarget(int x, int y) const
636 Tizen::Graphics::FloatPoint ptf((float) x, (float) y);
638 _ControlVisualElement* pRootControlElement =
639 dynamic_cast <_ControlVisualElement*>(_ControlManager::GetInstance()->GetTopVisibleWindowAt(Point(x, y))->GetVisualElement());
640 SysTryReturn(NID_UI, pRootControlElement, _UiObjectHandle(), E_SYSTEM, "[E_SYSTEM] System error occurred.");
642 _ControlVisualElement* pControlVisualElement = pRootControlElement->GetControlChildAtPoint(ptf);
643 SysTryReturn(NID_UI, pControlVisualElement, _UiObjectHandle(), E_SYSTEM, "[E_SYSTEM] System error occurred.");
645 _Control* pControl = static_cast <_Control*>(pControlVisualElement->GetUserData());
646 SysTryReturn(NID_UI, pControl, _UiObjectHandle(), E_SYSTEM, "[E_SYSTEM] System error occurred.");
648 return pControl->GetHandle();
652 _UiEventManager::SetKeyCapture(const _Control& control, _KeyCode keyCode)
654 __pEventManager->SetKeyCapture(control, keyCode);
656 _KeyEventManager* pKeyEventManager = _KeyEventManager::GetInstance();
657 SysAssert(pKeyEventManager != null);
659 pKeyEventManager->SetCapturingControl(control, keyCode, true);
663 _UiEventManager::ReleaseKeyCapture(const _Control& control, _KeyCode keyCode)
665 __pEventManager->ReleaseKeyCapture(control, keyCode);
667 _KeyEventManager* pKeyEventManager = _KeyEventManager::GetInstance();
668 SysAssert(pKeyEventManager != null);
670 pKeyEventManager->SetCapturingControl(control, keyCode, false);
674 _UiEventManager::RemoveAllEventListenerList(Tizen::Base::Collection::HashMapT<_UiEventType, Tizen::Base::Collection::LinkedListT<_IUiEventListener*>*>* pMap)
676 Tizen::Base::Collection::IMapEnumeratorT<_UiEventType, Tizen::Base::Collection::LinkedListT<_IUiEventListener*>*>* pMapEnumerator = pMap->GetMapEnumeratorN();
677 SysTryReturnVoidResult(NID_UI, pMapEnumerator, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
679 while (pMapEnumerator->MoveNext() == E_SUCCESS)
681 Tizen::Base::Collection::LinkedListT<_IUiEventListener*>* pListeners = null;
682 pMapEnumerator->GetValue(pListeners);
692 delete pMapEnumerator;
695 _UiEventManager::_UiEventManager(void)
696 : __pEventManager(new (std::nothrow) _EflUiEventManager)
698 unique_ptr<HashMapT<_UiEventType, LinkedListT<_IUiEventListener*>*> > pEventListenerMap(new (std::nothrow) HashMapT<_UiEventType, LinkedListT<_IUiEventListener*>*>);
699 SysTryReturnVoidResult(NID_UI, pEventListenerMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
701 result r = pEventListenerMap->Construct();
702 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
705 LinkedListT<_IUiEventListener*>* pTouchEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
706 SysTryReturnVoidResult(NID_UI, pTouchEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
708 r = pEventListenerMap->Add(_UI_EVENT_TOUCH, pTouchEventListeners);
709 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
712 LinkedListT<_IUiEventListener*>* pKeyEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
713 SysTryReturnVoidResult(NID_UI, pKeyEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
715 r = pEventListenerMap->Add(_UI_EVENT_KEY, pKeyEventListeners);
716 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
719 LinkedListT<_IUiEventListener*>* pFocusEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
720 SysTryReturnVoidResult(NID_UI, pFocusEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
722 r = pEventListenerMap->Add(_UI_EVENT_FOCUS, pFocusEventListeners);
723 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
726 LinkedListT <_IUiEventListener*>* pNotificationEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
727 SysTryReturnVoidResult(NID_UI, pNotificationEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
729 r = pEventListenerMap->Add(_UI_EVENT_NOTIFICAITON, pNotificationEventListeners);
730 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
733 unique_ptr<HashMapT<_UiEventType, LinkedListT<_IUiEventListener*>*> > pPostEventListenerMap(new (std::nothrow) HashMapT<_UiEventType, LinkedListT<_IUiEventListener*>*>);
734 SysTryReturnVoidResult(NID_UI, pPostEventListenerMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
736 r = pPostEventListenerMap->Construct();
737 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
740 LinkedListT<_IUiEventListener*>* pPostKeyEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
741 SysTryReturnVoidResult(NID_UI, pPostKeyEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
743 r = pPostEventListenerMap->Add(_UI_EVENT_KEY, pPostKeyEventListeners);
744 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
747 __pEventListenerMap = move(pEventListenerMap);
748 __pPostEventListenerMap = move(pPostEventListenerMap);
751 _UiEventManager::~_UiEventManager(void)
753 RemoveAllEventListenerList(__pEventListenerMap.get());
754 RemoveAllEventListenerList(__pPostEventListenerMap.get());