2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 #if defined(MULTI_WINDOW)
42 #include "FUi_Window.h"
46 using namespace Tizen::Base;
47 using namespace Tizen::Base::Collection;
48 using namespace Tizen::Graphics;
49 using namespace Tizen::Ui::Animations;
51 namespace Tizen { namespace Ui
54 _UiEventManager* _UiEventManager::__pInstance = null;
57 _UiEventManager::Initialize(void)
59 static pthread_once_t once_block = PTHREAD_ONCE_INIT;
63 pthread_once(&once_block, InitInstance);
68 _UiEventManager::Release(void)
75 _UiEventManager::GetInstance(void)
81 _UiEventManager::InitInstance(void)
85 __pInstance = new (std::nothrow) _UiEventManager;
86 SysAssert(__pInstance);
91 _UiEventManager::AddTouchEventListener(const _ITouchEventListener& listener)
93 return AddEventListener(_UI_EVENT_TOUCH, false, listener);
97 _UiEventManager::AddKeyEventListener(const _IKeyEventListener& listener)
99 return AddEventListener(_UI_EVENT_KEY, false, listener);
103 _UiEventManager::AddFocusEventListener(const _IFocusEventListener& listener)
105 return AddEventListener(_UI_EVENT_FOCUS, false, listener);
109 _UiEventManager::AddNotificationEventListener(const _INotificationEventListener& listener)
111 return AddEventListener(_UI_EVENT_NOTIFICAITON, false, listener);
115 _UiEventManager::RemoveTouchEventListener(const _ITouchEventListener& listener)
117 return RemoveEventListener(_UI_EVENT_TOUCH, false, listener);
121 _UiEventManager::RemoveKeyEventListener(const _IKeyEventListener& listener)
123 return RemoveEventListener(_UI_EVENT_KEY, false, listener);
127 _UiEventManager::RemoveFocusEventListener(const _IFocusEventListener& listener)
129 return RemoveEventListener(_UI_EVENT_FOCUS, false, listener);
133 _UiEventManager::RemoveNotificationEventListener(const _INotificationEventListener& listener)
135 return RemoveEventListener(_UI_EVENT_NOTIFICAITON, false, listener);
139 _UiEventManager::AddPostKeyEventListener(const _IKeyEventListener& listener)
141 return AddEventListener(_UI_EVENT_KEY, true, listener);
145 _UiEventManager::RemovePostKeyEventListener(const _IKeyEventListener& listener)
147 return RemoveEventListener(_UI_EVENT_KEY, true, listener);
151 _UiEventManager::SendEvent(const _UiEvent& event)
153 result r = E_SUCCESS;
161 _UiEventManager::PostEvent(const _UiEvent& event)
163 return __pEventManager->PostEvent(event);
167 _UiEventManager::GenerateKeyEvent(KeyState keyState, _KeyCode keyCode, _KeyModifier keyModifier, bool async)
169 result r = E_SUCCESS;
171 _UiObjectHandle uiObjectHandle = GetTarget();
172 if (uiObjectHandle.IsNull())
177 _UiEventRouteType routeType = (keyState == KEY_LONGPRESSED) ? _UI_EVENT_ROUTE_DIRECT : _UI_EVENT_ROUTE_TUNNEL_BUBBLE;
179 _KeyInfo keyInfo(keyState, keyCode, keyModifier, null);
181 _UiKeyEvent event(uiObjectHandle, keyInfo, routeType);
185 r = PostEvent(event);
189 r = SendEvent(event);
192 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
198 _UiEventManager::GenerateTouchEvent(_TouchStatus touchStatus, int x, int y, bool async)
200 result r = E_SUCCESS;
202 _UiObjectHandle uiObjectHandle = GetTarget(x, y);
203 if (uiObjectHandle.IsNull())
208 const unsigned long DEVICE_ID = 0;
211 unsigned int pointId = 0;
212 _UiEventRouteType routeType = _UI_EVENT_ROUTE_TUNNEL_BUBBLE;
214 _TouchManager* pTouchManager = _TouchManager::GetInstance();
215 SysTryReturn(NID_UI, pTouchManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
220 pointId = pTouchManager->GeneratePointId(DEVICE_ID);
223 case _TOUCH_LONG_PRESSED:
225 case _TOUCH_DOUBLE_PRESSED:
226 routeType = _UI_EVENT_ROUTE_DIRECT;
227 pointId = pTouchManager->GetPointId(DEVICE_ID);
231 pointId = pTouchManager->GetPointId(DEVICE_ID);
235 _TouchInfo touchInfo(pointId, touchStatus, current, false, 0);
236 _UiTouchEvent event(uiObjectHandle, touchInfo, routeType);
240 r = PostEvent(event);
244 r = SendEvent(event);
247 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
253 _UiEventManager::GetEventManager(void) const
255 return __pEventManager.get();
259 _UiEventManager::AddEventListener(_UiEventType eventType, bool postListener, const _IUiEventListener& listener)
261 result r = E_SUCCESS;
263 SysTryReturn(NID_UI, !IsListenerRegistered(eventType, postListener, listener), E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
265 LinkedListT <_IUiEventListener*>* pEventListeners = GetEventListeners(eventType, postListener);
268 pEventListeners->Add(const_cast <_IUiEventListener*>(&listener));
275 _UiEventManager::RemoveEventListener(_UiEventType eventType, bool postListener, const _IUiEventListener& listener)
277 result r = E_SUCCESS;
279 LinkedListT <_IUiEventListener*>* pEventListeners = GetEventListeners(eventType, postListener);
282 pEventListeners->Remove(const_cast <_IUiEventListener*>(&listener));
289 _UiEventManager::IsListenerRegistered(_UiEventType eventType, bool postListener, const _IUiEventListener& listener)
291 bool isRegistered = false;
293 LinkedListT <_IUiEventListener*>* pEventListeners = GetEventListeners(eventType, postListener);
296 Tizen::Base::Collection::IEnumeratorT <_IUiEventListener*>* pEnumerator = pEventListeners->GetEnumeratorN();
297 SysTryReturn(NID_UI, pEnumerator, false, E_SYSTEM, "[E_SYSTEM] System error occurred.");
299 while (pEnumerator->MoveNext() == E_SUCCESS)
301 _IUiEventListener* pEventListener = null;
302 pEnumerator->GetCurrent(pEventListener);
308 if (pEventListener == &listener)
322 _UiEventManager::Fire(const _UiEvent& event)
324 result r = E_SUCCESS;
326 bool isFiltered = false;
328 r = ProcessListener(event, isFiltered);
329 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
333 r = ProcessGlobalGesture(event, isFiltered);
334 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
337 if (event.GetEventType() == _UI_EVENT_TOUCH)
339 r = ProcessEvent(event, isFiltered);
340 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
342 else if (!isFiltered)
344 r = ProcessEvent(event, isFiltered);
345 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
351 LinkedListT <_IUiEventListener*>*
352 _UiEventManager::GetEventListeners(_UiEventType eventType, bool postListener) const
354 LinkedListT <_IUiEventListener*>* pEventListeners = null;
358 __pPostEventListenerMap->GetValue(eventType, pEventListeners);
362 result r = E_SUCCESS;
364 r = __pEventListenerMap->GetValue(eventType, pEventListeners);
365 SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
368 return pEventListeners;
372 _UiEventManager::ProcessListener(const _UiEvent& event, bool& isFiltered)
374 return ProcessListener(event, false, isFiltered);
378 _UiEventManager::ProcessPostListener(const _UiEvent& event, bool& isFiltered)
380 return ProcessListener(event, true, isFiltered);
384 _UiEventManager::ProcessListener(const _UiEvent& event, bool postListener, bool& isFiltered)
386 result r = E_SUCCESS;
388 LinkedListT <_IUiEventListener*>* pEventListeners = GetEventListeners(event.GetEventType(), postListener);
391 Tizen::Base::Collection::IEnumeratorT <_IUiEventListener*>* pEnumerator = pEventListeners->GetEnumeratorN();
392 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
394 while (pEnumerator->MoveNext() == E_SUCCESS)
396 _IUiEventListener* pEventListener = null;
398 pEnumerator->GetCurrent(pEventListener);
404 r = const_cast<_UiEvent&>(event).ProcessListener(*pEventListener, isFiltered);
418 _UiEventManager::ProcessEvent(const _UiEvent& event, bool& isFiltered)
420 result r = E_SUCCESS;
422 switch (event.GetRouteType())
424 case _UI_EVENT_ROUTE_TUNNEL_BUBBLE:
426 LinkedListT <_UiObjectHandle> tunnelingPath;
427 LinkedListT <_UiObjectHandle> bubblingPath;
429 r = MakeRoutingPath(tunnelingPath, bubblingPath, event);
433 ProcessTunnelingEvent(tunnelingPath, event, isFiltered);
435 if (event.GetEventType() == _UI_EVENT_TOUCH)
437 ProcessBubblingEvent(bubblingPath, event, isFiltered);
439 else if (!isFiltered)
441 ProcessBubblingEvent(bubblingPath, event, isFiltered);
447 case _UI_EVENT_ROUTE_DIRECT:
449 _ControlManager* pControlManager = _ControlManager::GetInstance();
450 SysTryReturn(NID_UI, pControlManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
452 const _Control* pTarget = pControlManager->GetObject(event.GetDestination());
455 r = const_cast<_UiEvent&>(event).ProcessEvent(*pTarget, isFiltered);
468 _UiEventManager::ProcessGlobalGesture(const _UiEvent& event, bool& isFiltered)
470 if (event.GetEventType() != _UI_EVENT_TOUCH)
475 if (event.GetAccessibilityEvent())
480 _ControlManager* pControlManager = _ControlManager::GetInstance();
481 SysTryReturn(NID_UI, pControlManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
483 _TouchManager* pTouchManager = _TouchManager::GetInstance();
484 SysTryReturn(NID_UI, pTouchManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
486 Tizen::Base::Collection::IListT<_TouchGestureDetector*>* pGestureList = pControlManager->GetGestureDetectorList();
487 if (!pGestureList || (pGestureList && (pGestureList->GetCount() <= 0)))
492 result r = E_SUCCESS;
494 Tizen::Base::Collection::IEnumeratorT <_TouchGestureDetector*>* pEnumerator = pGestureList->GetEnumeratorN();
495 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
497 _TouchGestureDetector* pGestureDetector = null;
498 while (pEnumerator->MoveNext() == E_SUCCESS)
500 pEnumerator->GetCurrent(pGestureDetector);
502 if (!pGestureDetector)
507 r = const_cast<_UiEvent&>(event).ProcessListener(*pGestureDetector, isFiltered);
520 _UiEventManager::MakeRoutingPath(Tizen::Base::Collection::LinkedListT <_UiObjectHandle>& tunnelingPath, Tizen::Base::Collection::LinkedListT <_UiObjectHandle>& bubblingPath, const _UiEvent& event)
522 result r = E_SUCCESS;
524 _ControlManager* pControlManager = _ControlManager::GetInstance();
525 SysTryReturn(NID_UI, pControlManager, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
527 _Control* pControl = pControlManager->GetObject(event.GetDestination());
528 SysTryReturn(NID_UI, pControl, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
531 _Control* pBubblingTarget = pControl;
532 while (pBubblingTarget)
534 bubblingPath.Add(pBubblingTarget->GetHandle());
535 pBubblingTarget = pBubblingTarget->GetParent();
539 for (int i = bubblingPath.GetCount() - 1; i > 0; i--)
541 _UiObjectHandle uiObjectHandle;
543 r = bubblingPath.GetAt(i, uiObjectHandle);
546 tunnelingPath.Add(uiObjectHandle);
554 _UiEventManager::ProcessTunnelingEvent(const Tizen::Base::Collection::LinkedListT <_UiObjectHandle>& routingPath, const _UiEvent& event, bool& isFiltered)
556 result r = E_SUCCESS;
558 Tizen::Base::Collection::IEnumeratorT <_UiObjectHandle>* pEnumerator = routingPath.GetEnumeratorN();
559 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
561 _UiObjectHandle uiObjectHandle;
562 while (pEnumerator->MoveNext() == E_SUCCESS)
564 pEnumerator->GetCurrent(uiObjectHandle);
565 if (uiObjectHandle.IsNull())
570 const _Control* pControl = event.GetControl(uiObjectHandle);
576 r = const_cast<_UiEvent&>(event).ProcessPreviewEvent(*pControl, isFiltered);
590 _UiEventManager::ProcessBubblingEvent(const Tizen::Base::Collection::LinkedListT <_UiObjectHandle>& routingPath, const _UiEvent& event, bool& isFiltered)
592 result r = E_SUCCESS;
594 Tizen::Base::Collection::IEnumeratorT <_UiObjectHandle>* pEnumerator = routingPath.GetEnumeratorN();
595 SysTryReturn(NID_UI, pEnumerator, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] System error occurred.");
597 _UiObjectHandle uiObjectHandle;
598 while (pEnumerator->MoveNext() == E_SUCCESS)
600 pEnumerator->GetCurrent(uiObjectHandle);
601 if (uiObjectHandle.IsNull())
606 const _Control* pControl = event.GetControl(uiObjectHandle);
612 r = const_cast<_UiEvent&>(event).ProcessEvent(*pControl, isFiltered);
614 if (!isFiltered && (event.GetDestination() == uiObjectHandle))
616 ProcessPostListener(event, isFiltered);
626 _UiEventManager::GetTarget(void) const
628 _Control* pControl = _ControlManager::GetInstance()->GetFocusedControl();
629 SysTryReturn(NID_UI, pControl, _UiObjectHandle(), E_SYSTEM, "[E_SYSTEM] System error occurred.");
631 return pControl->GetHandle();
635 _UiEventManager::GetTarget(int x, int y) const
637 Tizen::Graphics::FloatPoint ptf((float) x, (float) y);
639 #if !defined(MULTI_WINDOW)
640 _ControlVisualElement* pRootControlElement =
641 dynamic_cast <_ControlVisualElement*>(_ControlManager::GetInstance()->GetRoot().GetVisualElement());
643 _ControlVisualElement* pRootControlElement =
644 dynamic_cast <_ControlVisualElement*>(_ControlManager::GetInstance()->GetTopVisibleWindowAt(Point(x, y))->GetVisualElement());
646 SysTryReturn(NID_UI, pRootControlElement, _UiObjectHandle(), E_SYSTEM, "[E_SYSTEM] System error occurred.");
648 _ControlVisualElement* pControlVisualElement = pRootControlElement->GetControlChildAtPoint(ptf);
649 SysTryReturn(NID_UI, pControlVisualElement, _UiObjectHandle(), E_SYSTEM, "[E_SYSTEM] System error occurred.");
651 _Control* pControl = static_cast <_Control*>(pControlVisualElement->GetUserData());
652 SysTryReturn(NID_UI, pControl, _UiObjectHandle(), E_SYSTEM, "[E_SYSTEM] System error occurred.");
654 return pControl->GetHandle();
658 _UiEventManager::SetKeyCapture(const _Control& control, _KeyCode keyCode)
660 __pEventManager->SetKeyCapture(control, keyCode);
662 _KeyEventManager* pKeyEventManager = _KeyEventManager::GetInstance();
663 SysAssert(pKeyEventManager != null);
665 pKeyEventManager->SetCapturingControl(control, keyCode, true);
669 _UiEventManager::ReleaseKeyCapture(const _Control& control, _KeyCode keyCode)
671 __pEventManager->ReleaseKeyCapture(control, keyCode);
673 _KeyEventManager* pKeyEventManager = _KeyEventManager::GetInstance();
674 SysAssert(pKeyEventManager != null);
676 pKeyEventManager->SetCapturingControl(control, keyCode, false);
680 _UiEventManager::RemoveAllEventListenerList(Tizen::Base::Collection::HashMapT<_UiEventType, Tizen::Base::Collection::LinkedListT<_IUiEventListener*>*>* pMap)
682 Tizen::Base::Collection::IMapEnumeratorT<_UiEventType, Tizen::Base::Collection::LinkedListT<_IUiEventListener*>*>* pMapEnumerator = pMap->GetMapEnumeratorN();
683 SysTryReturnVoidResult(NID_UI, pMapEnumerator, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
685 while (pMapEnumerator->MoveNext() == E_SUCCESS)
687 Tizen::Base::Collection::LinkedListT<_IUiEventListener*>* pListeners = null;
688 pMapEnumerator->GetValue(pListeners);
698 delete pMapEnumerator;
701 _UiEventManager::_UiEventManager(void)
702 : __pEventManager(new (std::nothrow) _EflUiEventManager)
704 unique_ptr<HashMapT<_UiEventType, LinkedListT<_IUiEventListener*>*> > pEventListenerMap(new (std::nothrow) HashMapT<_UiEventType, LinkedListT<_IUiEventListener*>*>);
705 SysTryReturnVoidResult(NID_UI, pEventListenerMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
707 result r = pEventListenerMap->Construct();
708 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
711 LinkedListT<_IUiEventListener*>* pTouchEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
712 SysTryReturnVoidResult(NID_UI, pTouchEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
714 r = pEventListenerMap->Add(_UI_EVENT_TOUCH, pTouchEventListeners);
715 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
718 LinkedListT<_IUiEventListener*>* pKeyEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
719 SysTryReturnVoidResult(NID_UI, pKeyEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
721 r = pEventListenerMap->Add(_UI_EVENT_KEY, pKeyEventListeners);
722 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
725 LinkedListT<_IUiEventListener*>* pFocusEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
726 SysTryReturnVoidResult(NID_UI, pFocusEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
728 r = pEventListenerMap->Add(_UI_EVENT_FOCUS, pFocusEventListeners);
729 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
732 LinkedListT <_IUiEventListener*>* pNotificationEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
733 SysTryReturnVoidResult(NID_UI, pNotificationEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
735 r = pEventListenerMap->Add(_UI_EVENT_NOTIFICAITON, pNotificationEventListeners);
736 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
739 unique_ptr<HashMapT<_UiEventType, LinkedListT<_IUiEventListener*>*> > pPostEventListenerMap(new (std::nothrow) HashMapT<_UiEventType, LinkedListT<_IUiEventListener*>*>);
740 SysTryReturnVoidResult(NID_UI, pPostEventListenerMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
742 r = pPostEventListenerMap->Construct();
743 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
746 LinkedListT<_IUiEventListener*>* pPostKeyEventListeners = new (std::nothrow) LinkedListT<_IUiEventListener*>;
747 SysTryReturnVoidResult(NID_UI, pPostKeyEventListeners, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
749 r = pPostEventListenerMap->Add(_UI_EVENT_KEY, pPostKeyEventListeners);
750 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
753 __pEventListenerMap = move(pEventListenerMap);
754 __pPostEventListenerMap = move(pPostEventListenerMap);
757 _UiEventManager::~_UiEventManager(void)
759 RemoveAllEventListenerList(__pEventListenerMap.get());
760 RemoveAllEventListenerList(__pPostEventListenerMap.get());