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_FocusManagerImpl.cpp
19 * @brief This is the implementation file for _FocusManagerImpl class.
25 #include <unique_ptr.h>
26 #include "FUi_FocusManagerImpl.h"
27 #include "FUi_ControlImpl.h"
28 #include "FUi_WindowImpl.h"
29 #include "FUi_ControlManager.h"
30 #include "FUiCtrl_Form.h"
31 #include "FUi_UiEventManager.h"
32 #include "FUi_ResourceManager.h"
33 #include "FUi_UiKeyEvent.h"
34 #include "FUi_Window.h"
35 #include "FUiCtrl_Frame.h"
38 using namespace Tizen::Base::Collection;
39 using namespace Tizen::Graphics;
40 using namespace Tizen::Ui;
41 using namespace Tizen::Ui::Controls;
42 using namespace Tizen::Ui::Animations;
44 namespace Tizen { namespace Ui
46 ////////////////////////////////////////////////////////////////////////////////
47 /// _FocusManagerImpl class Lifecycle
48 _FocusManagerImpl* _FocusManagerImpl::__pInstance = null;
50 _FocusManagerImpl::_FocusManagerImpl(void)
51 : __pCurrentFocusUiControl(null)
52 , __isFocusMode(false)
53 , __focusDirection(FOCUS_DIRECTION_DOWNWARD)
56 _UiEventManager* pUiEventManager = _UiEventManager::GetInstance();
59 result r = pUiEventManager->AddPostKeyEventListener(*this);
60 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
62 r = pUiEventManager->AddTouchEventListener(*this);
63 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
69 _FocusManagerImpl::~_FocusManagerImpl(void)
75 _FocusManagerImpl::Initialize(void)
77 static pthread_once_t once_block = PTHREAD_ONCE_INIT;
79 if (__pInstance == null)
81 pthread_once(&once_block, InitializeInstance);
86 _FocusManagerImpl::GetInstance(void)
92 _FocusManagerImpl::InitializeInstance(void)
96 if (__pInstance == null)
98 __pInstance = new (std::nothrow) _FocusManagerImpl;
99 SysTryReturnVoidResult(NID_UI, __pInstance != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
104 _FocusManagerImpl::ReleaseInstance(void)
113 ////////////////////////////////////////////////////////////////////////////////
114 /// _FocusManagerImpl class Operation
117 _FocusManagerImpl::GetCurrentFocusOwner(void) const
119 _Control* pFocus = _ControlManager::GetInstance()->GetFocusControl();
125 _ControlImpl* pFocusImpl = static_cast <_ControlImpl*>(pFocus->GetUserData());
126 SysAssert(pFocusImpl);
133 _FocusManagerImpl::GetCurrentFocusedWindow(void) const
135 _Control* pFocus = _ControlManager::GetInstance()->GetFocusControl();
140 _Window* pWindow = pFocus->GetRootWindow();
143 _WindowImpl* pWindowImpl = static_cast <_WindowImpl*>(static_cast <_ControlImpl*>(pWindow->GetUserData()));
144 SysAssert(pWindowImpl);
150 _FocusManagerImpl::IsFocusModeStateEnabled(void) const
152 return __isFocusMode;
156 _FocusManagerImpl::GetNextIndex(int currentIndex, FocusDirection focusDirection, const IListT<_Control*>* pFocusControlList) const
158 int nextIndex = currentIndex;
159 if (focusDirection == FOCUS_DIRECTION_DOWNWARD)
162 if (nextIndex == pFocusControlList->GetCount())
172 nextIndex = pFocusControlList->GetCount() - 1;
181 _FocusManagerImpl::IsFocusable(_Control* pControl) const
183 bool isFocusalbe = pControl->IsFocusable();
184 bool enableState = pControl->IsEnabled();
185 bool visibleState = pControl->IsVisible();
186 bool isNavigatable = pControl->IsFocusNavigateEnabled();
187 if (enableState && visibleState && isFocusalbe && isNavigatable)
195 _FocusManagerImpl::FindTraversalControlFromChild(_Control* pControl)
197 IListT<_Control*>* pFocusControlList = null;
198 bool findNextFocusControl = false;
200 _Window* pTop = pControl->GetRootWindow();
203 pFocusControlList = pTop->GetFocusList();
206 if (pFocusControlList)
208 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
210 while (pEnum->MoveNext() == E_SUCCESS)
212 _Control* pEnumeratorControl = null;
213 pEnum->GetCurrent(pEnumeratorControl);
215 //Find current focused control
216 if (pControl == pEnumeratorControl)
218 findNextFocusControl = true;
223 if (findNextFocusControl == false)
225 _Control* pParent = pControl->GetParent();
228 return FindTraversalControlFromChild(pParent);
236 _FocusManagerImpl::IsFocusControlListControl(_Control* pControl) const
238 IListT<_Control*>* pFocusControlList = null;
240 _Window* pTop = pControl->GetRootWindow();
243 pFocusControlList = pTop->GetFocusList();
246 if (pFocusControlList)
248 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
249 while (pEnum->MoveNext() == E_SUCCESS)
251 _Control* pEnumeratorControl = null;
252 pEnum->GetCurrent(pEnumeratorControl);
254 //Find current focused control
255 if (pControl == pEnumeratorControl)
266 _FocusManagerImpl::StartFocusTraversal(_Control* pControl, FocusDirection focusDirection)
268 _Control* pOriginalControl = pControl;
269 _Window* pTop = pControl->GetRootWindow();
274 bool isWindowEnabled = pTop->IsEnabled();
275 if (!isWindowEnabled)
279 _Control* pFocusTraversalControl = pTop->GetFocusTraversalControl(pControl);
280 if (pFocusTraversalControl)
282 pControl = pFocusTraversalControl;
286 _Control* pTraversalControl = FindTraversalControlFromChild(pControl);
287 pTop->SetFocusTraversalControl(pTraversalControl, true);
291 bool focusMode = pControl->IsFocusModeStateEnabled();
292 if (__isFocusMode == false)
294 __isFocusMode = true;
295 if (pOriginalControl)
297 pOriginalControl->OnFocusModeStateChanged();
301 if (focusMode == false && pControl->IsFocused())
303 if (IsFocusable(pControl))
305 if (IsFocusControlListControl(pControl))
307 pTop->SetFocusTraversalControl(pControl, true);
309 pControl->DrawFocus();
314 if (focusDirection == FOCUS_DIRECTION_DOWNWARD)
316 _Control* pFocusControl = pControl->GetNextFocus();
319 pFocusControl->SetFocused();
320 pFocusControl->DrawFocus();
321 pTop->SetFocusTraversalControl(pFocusControl, true);
327 _Control* pFocusControl = pControl->GetPreviousFocus();
330 pFocusControl->SetFocused();
331 pFocusControl->DrawFocus();
332 pTop->SetFocusTraversalControl(pFocusControl, true);
337 IListT<_Control*>* pFocusControlList = null;
339 pFocusControlList = pTop->GetFocusList();
341 if (pFocusControlList)
343 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
344 SysTryReturnVoidResult(NID_UI_CTRL, pEnum, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
346 bool findNextFocusControl = false;
347 _Control* pNextFocusControl = null;
349 int loopCount = pFocusControlList->GetCount() + 1;
350 while (pEnum->MoveNext() == E_SUCCESS)
352 _Control* pEnumeratorControl = null;
353 pEnum->GetCurrent(pEnumeratorControl);
355 //Find current focused control
356 if (pControl == pEnumeratorControl)
358 //Find next focusable control.
359 index = GetNextIndex(index, focusDirection, pFocusControlList);
361 while (pFocusControlList->GetAt(index, pNextFocusControl) == E_SUCCESS)
364 if (IsFocusable(pNextFocusControl))
366 if (pNextFocusControl != pControl)
368 pNextFocusControl->SetFocused();
372 pTop->SetFocusControl(pNextFocusControl, true);
374 findNextFocusControl = true;
380 if (loopCount == count)
384 index = GetNextIndex(index, focusDirection, pFocusControlList);
390 if (findNextFocusControl == true)
398 pTop->SetFocusTraversalControl(pNextFocusControl, true);
399 if (pNextFocusControl && findNextFocusControl == true)
401 _Control* pParentControl = pNextFocusControl->GetParent();
404 pParentControl->OnChildControlFocusMoved(*pNextFocusControl);
405 while(pParentControl)
407 pParentControl->OnDescendantControlFocusMoved(*pNextFocusControl);
408 pParentControl = pParentControl->GetParent();
411 pNextFocusControl->DrawFocus();
417 _FocusManagerImpl::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
419 Ecore_X_Window rootWindow = ecore_x_window_root_first_get();
420 Ecore_X_Atom keyboardExist = ecore_x_atom_get("X External Keyboard Exist");
421 unsigned int keyboardNumber = 0;
422 int ret = ecore_x_window_prop_card32_get(rootWindow, keyboardExist, &keyboardNumber, 1);
423 if (keyboardNumber == 0)
427 _KeyCode keyCode = keyInfo.GetKeyCode();
428 __focusDirection = FOCUS_DIRECTION_DOWNWARD;
429 _Control* pControl = const_cast<_Control*> (&source);
435 if (keyInfo.GetKeyModifier() & _KEY_MODIFIER_SHIFT)
437 __focusDirection = FOCUS_DIRECTION_UPWARD;
443 __focusDirection = FOCUS_DIRECTION_UPWARD;
448 __focusDirection = FOCUS_DIRECTION_DOWNWARD;
456 StartFocusTraversal(pControl, __focusDirection);
460 bool _FocusManagerImpl::IsForwardDirection(void) const
462 if (__focusDirection == FOCUS_DIRECTION_DOWNWARD)
470 _FocusManagerImpl::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
476 _FocusManagerImpl::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
478 _Control* pSourceControl = const_cast<_Control*>(&source);
479 __isFocusMode = false;
481 _Window* pTop = source.GetRootWindow();
484 _Control* pControl = pTop->GetFocusControl(pSourceControl);
487 pControl->OnFocusModeStateChanged();
488 pControl->RemoveFocusRing();
496 _FocusManagerImpl::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
502 _FocusManagerImpl:: OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
508 _FocusManagerImpl::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)