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 result r = _UiEventManager::GetInstance()->AddPostKeyEventListener(*this);
57 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
59 r = _UiEventManager::GetInstance()->AddTouchEventListener(*this);
60 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
65 _FocusManagerImpl::~_FocusManagerImpl(void)
71 _FocusManagerImpl::Initialize(void)
73 static pthread_once_t once_block = PTHREAD_ONCE_INIT;
75 if (__pInstance == null)
77 pthread_once(&once_block, InitializeInstance);
82 _FocusManagerImpl::GetInstance(void)
88 _FocusManagerImpl::InitializeInstance(void)
92 if (__pInstance == null)
94 __pInstance = new (std::nothrow) _FocusManagerImpl;
95 SysTryReturnVoidResult(NID_UI, __pInstance != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
100 _FocusManagerImpl::ReleaseInstance(void)
109 ////////////////////////////////////////////////////////////////////////////////
110 /// _FocusManagerImpl class Operation
113 _FocusManagerImpl::GetCurrentFocusOwner(void) const
115 _Control* pFocus = _ControlManager::GetInstance()->GetFocusControl();
121 _ControlImpl* pFocusImpl = static_cast <_ControlImpl*>(pFocus->GetUserData());
122 SysAssert(pFocusImpl);
129 _FocusManagerImpl::GetCurrentFocusedWindow(void) const
131 _Control* pFocus = _ControlManager::GetInstance()->GetFocusControl();
136 _Window* pWindow = pFocus->GetRootWindow();
139 _WindowImpl* pWindowImpl = static_cast <_WindowImpl*>(static_cast <_ControlImpl*>(pWindow->GetUserData()));
140 SysAssert(pWindowImpl);
146 _FocusManagerImpl::IsFocusModeStateEnabled(void) const
148 return __isFocusMode;
152 _FocusManagerImpl::GetNextIndex(int currentIndex, FocusDirection focusDirection, const IListT<_Control*>* pFocusControlList) const
154 int nextIndex = currentIndex;
155 if (focusDirection == FOCUS_DIRECTION_DOWNWARD)
158 if (nextIndex == pFocusControlList->GetCount())
168 nextIndex = pFocusControlList->GetCount() - 1;
177 _FocusManagerImpl::IsFocusable(_Control* pControl) const
179 bool isFocusalbe = pControl->IsFocusable();
180 bool enableState = pControl->IsEnabled();
181 bool visibleState = pControl->IsVisible();
182 bool isNavigatable = pControl->IsFocusNavigateEnabled();
183 if (enableState && visibleState && isFocusalbe && isNavigatable)
191 _FocusManagerImpl::FindTraversalControlFromChild(_Control* pControl)
193 IListT<_Control*>* pFocusControlList = null;
194 bool findNextFocusControl = false;
196 _Window* pTop = pControl->GetRootWindow();
199 pFocusControlList = pTop->GetFocusList();
202 if (pFocusControlList)
204 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
206 while (pEnum->MoveNext() == E_SUCCESS)
208 _Control* pEnumeratorControl = null;
209 pEnum->GetCurrent(pEnumeratorControl);
211 //Find current focused control
212 if (pControl == pEnumeratorControl)
214 findNextFocusControl = true;
219 if (findNextFocusControl == false)
221 _Control* pParent = pControl->GetParent();
224 return FindTraversalControlFromChild(pParent);
232 _FocusManagerImpl::IsFocusControlListControl(_Control* pControl) const
234 IListT<_Control*>* pFocusControlList = null;
236 _Window* pTop = pControl->GetRootWindow();
239 pFocusControlList = pTop->GetFocusList();
242 if (pFocusControlList)
244 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
245 while (pEnum->MoveNext() == E_SUCCESS)
247 _Control* pEnumeratorControl = null;
248 pEnum->GetCurrent(pEnumeratorControl);
250 //Find current focused control
251 if (pControl == pEnumeratorControl)
262 _FocusManagerImpl::StartFocusTraversal(_Control* pControl, FocusDirection focusDirection)
264 _Window* pTop = pControl->GetRootWindow();
269 bool isWindowEnabled = pTop->IsEnabled();
270 if (!isWindowEnabled)
274 _Control* pFocusTraversalControl = pTop->GetFocusTraversalControl(pControl);
275 if (pFocusTraversalControl)
277 pControl = pFocusTraversalControl;
281 _Control* pTraversalControl = FindTraversalControlFromChild(pControl);
282 pTop->SetFocusTraversalControl(pTraversalControl, true);
286 bool focusMode = pControl->IsFocusModeStateEnabled();
287 if (__isFocusMode == false)
289 __isFocusMode = true;
290 pControl->OnFocusModeStateChanged();
293 if (focusMode == false && pControl->IsFocused())
295 if (IsFocusable(pControl))
297 if (IsFocusControlListControl(pControl))
299 pTop->SetFocusTraversalControl(pControl, true);
301 pControl->DrawFocus();
306 if (focusDirection == FOCUS_DIRECTION_DOWNWARD)
308 _Control* pFocusControl = pControl->GetNextFocus();
311 pFocusControl->SetFocused();
312 pFocusControl->DrawFocus();
313 pTop->SetFocusTraversalControl(pFocusControl, true);
319 _Control* pFocusControl = pControl->GetPreviousFocus();
322 pFocusControl->SetFocused();
323 pFocusControl->DrawFocus();
324 pTop->SetFocusTraversalControl(pFocusControl, true);
329 IListT<_Control*>* pFocusControlList = null;
331 pFocusControlList = pTop->GetFocusList();
333 if (pFocusControlList)
335 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
336 SysTryReturnVoidResult(NID_UI_CTRL, pEnum, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
338 bool findNextFocusControl = false;
339 _Control* pNextFocusControl = null;
341 int loopCount = pFocusControlList->GetCount() + 1;
342 while (pEnum->MoveNext() == E_SUCCESS)
344 _Control* pEnumeratorControl = null;
345 pEnum->GetCurrent(pEnumeratorControl);
347 //Find current focused control
348 if (pControl == pEnumeratorControl)
350 //Find next focusable control.
351 index = GetNextIndex(index, focusDirection, pFocusControlList);
353 while (pFocusControlList->GetAt(index, pNextFocusControl) == E_SUCCESS)
356 if (IsFocusable(pNextFocusControl))
358 if (pNextFocusControl != pControl)
360 pNextFocusControl->SetFocused();
364 pTop->SetFocusControl(pNextFocusControl, true);
366 findNextFocusControl = true;
372 if (loopCount == count)
376 index = GetNextIndex(index, focusDirection, pFocusControlList);
382 if (findNextFocusControl == true)
390 pTop->SetFocusTraversalControl(pNextFocusControl, true);
391 if (pNextFocusControl && findNextFocusControl == true)
393 _Control* pParentControl = pNextFocusControl->GetParent();
396 pParentControl->OnChildControlFocusMoved(*pNextFocusControl);
397 while(pParentControl)
399 pParentControl->OnDescendantControlFocusMoved(*pNextFocusControl);
400 pParentControl = pParentControl->GetParent();
403 pNextFocusControl->DrawFocus();
409 _FocusManagerImpl::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
411 Ecore_X_Window rootWindow = ecore_x_window_root_first_get();
412 Ecore_X_Atom keyboardExist = ecore_x_atom_get("X External Keyboard Exist");
413 unsigned int keyboardNumber = 0;
414 int ret = ecore_x_window_prop_card32_get(rootWindow, keyboardExist, &keyboardNumber, 1);
415 if (keyboardNumber == 0)
419 _KeyCode keyCode = keyInfo.GetKeyCode();
420 __focusDirection = FOCUS_DIRECTION_DOWNWARD;
421 _Control* pControl = const_cast<_Control*> (&source);
427 if (keyInfo.GetKeyModifier() & _KEY_MODIFIER_SHIFT)
429 __focusDirection = FOCUS_DIRECTION_UPWARD;
435 __focusDirection = FOCUS_DIRECTION_UPWARD;
440 __focusDirection = FOCUS_DIRECTION_DOWNWARD;
448 StartFocusTraversal(pControl, __focusDirection);
452 bool _FocusManagerImpl::IsForwardDirection(void) const
454 if (__focusDirection == FOCUS_DIRECTION_DOWNWARD)
462 _FocusManagerImpl::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
468 _FocusManagerImpl::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
470 _Control* pSourceControl = const_cast<_Control*>(&source);
471 __isFocusMode = false;
473 _Window* pTop = source.GetRootWindow();
476 _Control* pFocusTraversalControl = pTop->GetFocusTraversalControl(pSourceControl);
477 if (pFocusTraversalControl)
479 pFocusTraversalControl->OnFocusModeStateChanged();
480 pFocusTraversalControl->RemoveFocusRing();
488 _FocusManagerImpl::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
494 _FocusManagerImpl:: OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
500 _FocusManagerImpl::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)