Changed indicator bg color.
[platform/framework/native/uifw.git] / src / ui / FUi_FocusManagerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
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.
16 //
17 /**
18 * @file             FUi_FocusManagerImpl.cpp
19 * @brief                This is the implementation file for _FocusManagerImpl class.
20 * @version              2.0
21 *
22 */
23
24 #include <Ecore.h>
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"
36
37 using namespace std;
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;
43
44 namespace Tizen { namespace Ui
45 {
46 ////////////////////////////////////////////////////////////////////////////////
47 /// _FocusManagerImpl class Lifecycle
48 _FocusManagerImpl* _FocusManagerImpl::__pInstance = null;
49
50 _FocusManagerImpl::_FocusManagerImpl(void)
51         : __pCurrentFocusUiControl(null)
52         , __isFocusMode(false)
53         , __focusDirection(FOCUS_DIRECTION_DOWNWARD)
54 {
55 #ifdef _FOCUS_UI_
56         result r = _UiEventManager::GetInstance()->AddPostKeyEventListener(*this);
57         SysTryReturnVoidResult(NID_UI,  r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
58
59         r = _UiEventManager::GetInstance()->AddTouchEventListener(*this);
60         SysTryReturnVoidResult(NID_UI,  r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
61 #endif
62 }
63
64
65 _FocusManagerImpl::~_FocusManagerImpl(void)
66 {
67         // NOTHING
68 }
69
70 void
71 _FocusManagerImpl::Initialize(void)
72 {
73         static pthread_once_t once_block = PTHREAD_ONCE_INIT;
74
75         if (__pInstance == null)
76         {
77                 pthread_once(&once_block, InitializeInstance);
78         }
79 }
80
81 _FocusManagerImpl*
82 _FocusManagerImpl::GetInstance(void)
83 {
84         return __pInstance;
85 }
86
87 void
88 _FocusManagerImpl::InitializeInstance(void)
89 {
90         ClearLastResult();
91
92         if (__pInstance == null)
93         {
94                 __pInstance = new (std::nothrow) _FocusManagerImpl;
95                 SysTryReturnVoidResult(NID_UI, __pInstance != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
96         }
97 }
98
99 void
100 _FocusManagerImpl::ReleaseInstance(void)
101 {
102         if (__pInstance)
103         {
104                 delete __pInstance;
105                 __pInstance = null;
106         }
107 }
108
109 ////////////////////////////////////////////////////////////////////////////////
110 /// _FocusManagerImpl class Operation
111
112 _ControlImpl*
113 _FocusManagerImpl::GetCurrentFocusOwner(void) const
114 {
115         _Control* pFocus = _ControlManager::GetInstance()->GetFocusControl();
116         if(pFocus == null)
117         {
118                 return null;
119         }
120
121         _ControlImpl* pFocusImpl = static_cast <_ControlImpl*>(pFocus->GetUserData());
122         SysAssert(pFocusImpl);
123
124         return pFocusImpl;
125 }
126
127
128 _WindowImpl*
129 _FocusManagerImpl::GetCurrentFocusedWindow(void) const
130 {
131         _Control* pFocus = _ControlManager::GetInstance()->GetFocusControl();
132         if(pFocus == null)
133         {
134                 return null;
135         }
136         _Window* pWindow = pFocus->GetRootWindow();
137         SysAssert(pWindow);
138
139         _WindowImpl* pWindowImpl = static_cast <_WindowImpl*>(static_cast <_ControlImpl*>(pWindow->GetUserData()));
140         SysAssert(pWindowImpl);
141
142         return pWindowImpl;
143 }
144
145 bool
146 _FocusManagerImpl::IsFocusModeStateEnabled(void) const
147 {
148         return __isFocusMode;
149 }
150
151 int
152 _FocusManagerImpl::GetNextIndex(int currentIndex, FocusDirection focusDirection, const IListT<_Control*>* pFocusControlList) const
153 {
154         int nextIndex = currentIndex;
155         if (focusDirection == FOCUS_DIRECTION_DOWNWARD)
156         {
157                 ++nextIndex;
158                 if (nextIndex == pFocusControlList->GetCount())
159                 {
160                         nextIndex = 0;
161                 }
162         }
163         else
164         {
165                 --nextIndex;
166                 if (nextIndex  < 0)
167                 {
168                         nextIndex = pFocusControlList->GetCount() - 1;
169                 }
170         }
171         return nextIndex;
172
173
174 }
175
176 bool
177 _FocusManagerImpl::IsFocusable(_Control* pControl) const
178 {
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)
184         {
185                 return true;
186         }
187         return false;
188 }
189
190 _Control*
191 _FocusManagerImpl::FindTraversalControlFromChild(_Control* pControl)
192 {
193         IListT<_Control*>* pFocusControlList =  null;
194         bool findNextFocusControl = false;
195
196         _Window* pTop = pControl->GetRootWindow();
197         if (pTop)
198         {
199                 pFocusControlList = pTop->GetFocusList();
200         }
201
202         if (pFocusControlList)
203         {
204                 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
205
206                 while (pEnum->MoveNext() == E_SUCCESS)
207                 {
208                         _Control* pEnumeratorControl = null;
209                         pEnum->GetCurrent(pEnumeratorControl);
210
211                         //Find current focused control
212                         if (pControl == pEnumeratorControl)
213                         {
214                                 findNextFocusControl = true;
215                         }
216                 }
217         }
218
219         if (findNextFocusControl == false)
220         {
221                 _Control* pParent = pControl->GetParent();
222                 if (pParent)
223                 {
224                         return FindTraversalControlFromChild(pParent);
225                 }
226         }
227
228         return pControl;
229 }
230
231 bool
232 _FocusManagerImpl::IsFocusControlListControl(_Control* pControl) const
233 {
234         IListT<_Control*>* pFocusControlList =  null;
235
236         _Window* pTop = pControl->GetRootWindow();
237         if (pTop)
238         {
239                 pFocusControlList = pTop->GetFocusList();
240         }
241
242         if (pFocusControlList)
243         {
244                 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
245                 while (pEnum->MoveNext() == E_SUCCESS)
246                 {
247                         _Control* pEnumeratorControl = null;
248                         pEnum->GetCurrent(pEnumeratorControl);
249
250                         //Find current focused control
251                         if (pControl == pEnumeratorControl)
252                         {
253                                 return true;
254                         }
255                 }
256         }
257
258         return false;
259 }
260
261 void
262 _FocusManagerImpl::StartFocusTraversal(_Control* pControl, FocusDirection focusDirection)
263 {
264         _Window* pTop = pControl->GetRootWindow();
265         if (pTop == null)
266         {
267                 return;
268         }
269         bool isWindowEnabled = pTop->IsEnabled();
270         if (!isWindowEnabled)
271         {
272                 return;
273         }
274         _Control* pFocusTraversalControl = pTop->GetFocusTraversalControl(pControl);
275         if (pFocusTraversalControl)
276         {
277                 pControl = pFocusTraversalControl;
278         }
279         else
280         {
281                 _Control* pTraversalControl = FindTraversalControlFromChild(pControl);
282                 pTop->SetFocusTraversalControl(pTraversalControl, true);
283         }
284
285
286         bool focusMode = pControl->IsFocusModeStateEnabled();
287         if (__isFocusMode == false)
288         {
289                 __isFocusMode = true;
290                 pControl->OnFocusModeStateChanged();
291         }
292
293         if (focusMode == false && pControl->IsFocused())
294         {
295                 if (IsFocusable(pControl))
296                 {
297                         if (IsFocusControlListControl(pControl))
298                         {
299                                 pTop->SetFocusTraversalControl(pControl, true);
300                         }
301                         pControl->DrawFocus();
302                         return;
303                 }
304         }
305
306         if (focusDirection == FOCUS_DIRECTION_DOWNWARD)
307         {
308                 _Control* pFocusControl =  pControl->GetNextFocus();
309                 if (pFocusControl)
310                 {
311                         pFocusControl->SetFocused();
312                         pFocusControl->DrawFocus();
313                         pTop->SetFocusTraversalControl(pFocusControl, true);
314                         return;
315                 }
316         }
317         else
318         {
319                 _Control* pFocusControl =  pControl->GetPreviousFocus();
320                 if (pFocusControl)
321                 {
322                         pFocusControl->SetFocused();
323                         pFocusControl->DrawFocus();
324                         pTop->SetFocusTraversalControl(pFocusControl, true);
325                         return;
326                 }
327         }
328
329         IListT<_Control*>* pFocusControlList =  null;
330
331         pFocusControlList = pTop->GetFocusList();
332
333         if (pFocusControlList)
334         {
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.");
337                 int index = 0;
338                 bool findNextFocusControl = false;
339                 _Control* pNextFocusControl = null;
340                 int count = 0;
341                 int loopCount = pFocusControlList->GetCount() + 1;
342                 while (pEnum->MoveNext() == E_SUCCESS)
343                 {
344                         _Control* pEnumeratorControl = null;
345                         pEnum->GetCurrent(pEnumeratorControl);
346
347                         //Find current focused control
348                         if (pControl == pEnumeratorControl)
349                         {
350                         //Find next focusable control.
351                         index = GetNextIndex(index, focusDirection, pFocusControlList);
352                         count ++;
353                                 while (pFocusControlList->GetAt(index, pNextFocusControl) == E_SUCCESS)
354                                 {
355                                         
356                                         if (IsFocusable(pNextFocusControl))
357                                         {
358                                                 if (pNextFocusControl != pControl)
359                                                 {
360                                                     pNextFocusControl->SetFocused();
361                                                 }
362                                                 else
363                                                 {
364                                                         pTop->SetFocusControl(pNextFocusControl, true);
365                                                 }
366                                                 findNextFocusControl = true;
367                                                 break;
368                                         }
369                                         else
370                                         {
371                                                 count ++;
372                                                 if (loopCount == count) 
373                                                 {
374                                                         return;
375                                                 }
376                                                 index = GetNextIndex(index, focusDirection, pFocusControlList);
377                                         }
378
379                                 }
380                         }
381
382                         if (findNextFocusControl == true)
383                         {
384                                 break;
385                         }
386
387                         index ++;
388                 }
389
390                 pTop->SetFocusTraversalControl(pNextFocusControl, true);
391                 if (pNextFocusControl && findNextFocusControl == true)
392                 {
393                         _Control* pParentControl =  pNextFocusControl->GetParent();
394                         if (pParentControl)
395                         {
396                                 pParentControl->OnChildControlFocusMoved(*pNextFocusControl);
397                                 while(pParentControl)
398                                 {
399                                         pParentControl->OnDescendantControlFocusMoved(*pNextFocusControl);
400                                         pParentControl = pParentControl->GetParent();
401                                 }
402                         }
403                         pNextFocusControl->DrawFocus();
404                 }
405         }
406 }
407
408 bool
409 _FocusManagerImpl::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
410 {
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)
416         {
417                 return false;
418         }
419         _KeyCode keyCode = keyInfo.GetKeyCode();
420         __focusDirection = FOCUS_DIRECTION_DOWNWARD;
421         _Control* pControl = const_cast<_Control*> (&source);
422
423         switch(keyCode)
424         {
425         case _KEY_TAB :
426                 {
427                         if (keyInfo.GetKeyModifier() & _KEY_MODIFIER_SHIFT)
428                         {
429                                 __focusDirection = FOCUS_DIRECTION_UPWARD;
430                         }                       
431                         break;
432                 }
433         case _KEY_UP :
434                 {
435                         __focusDirection = FOCUS_DIRECTION_UPWARD;
436                         break;
437                 }
438         case _KEY_DOWN :
439                 {
440                         __focusDirection = FOCUS_DIRECTION_DOWNWARD;
441                         break;
442                 }
443         default :
444                 {
445                         return false;
446                 }       
447         }
448         StartFocusTraversal(pControl, __focusDirection);        
449         return false;
450 }
451
452 bool _FocusManagerImpl::IsForwardDirection(void) const
453 {
454         if (__focusDirection == FOCUS_DIRECTION_DOWNWARD)
455         {
456                 return true;
457         }
458         return false;
459 }
460
461 bool
462 _FocusManagerImpl::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
463 {
464         return false;
465 }
466
467 bool
468 _FocusManagerImpl::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
469 {
470         _Control* pSourceControl = const_cast<_Control*>(&source);
471         __isFocusMode = false;
472
473         _Window* pTop = source.GetRootWindow();
474         if (pTop)
475         {
476                 _Control* pFocusTraversalControl = pTop->GetFocusTraversalControl(pSourceControl);
477                 if (pFocusTraversalControl)
478                 {
479                         pFocusTraversalControl->OnFocusModeStateChanged();
480                         pFocusTraversalControl->RemoveFocusRing();
481                 }
482         }
483
484         return false;
485 }
486
487 bool
488 _FocusManagerImpl::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
489 {
490         return false;
491 }
492
493 bool
494 _FocusManagerImpl:: OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
495 {
496         return false;
497 }
498
499 bool
500 _FocusManagerImpl::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
501 {
502         return false;
503 }
504 } } //Tizen::Ui
505