b7738d1ac776bc93be917a724dcdd6945443548e
[framework/osp/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 <unique_ptr.h>
25 #include "FUi_FocusManagerImpl.h"
26 #include "FUi_ControlImpl.h"
27 #include "FUi_WindowImpl.h"
28 #include "FUi_ControlManager.h"
29 #include "FUiCtrl_Form.h"
30 #include "FUi_UiEventManager.h"
31 #include "FUi_ResourceManager.h"
32 #include "FUi_UiKeyEvent.h"
33 #include "FUi_Window.h"
34 #include "FUiCtrl_Frame.h"
35
36 using namespace std;
37 using namespace Tizen::Base::Collection;
38 using namespace Tizen::Graphics;
39 using namespace Tizen::Ui;
40 using namespace Tizen::Ui::Controls;
41 using namespace Tizen::Ui::Animations;
42
43 namespace Tizen { namespace Ui
44 {
45 ////////////////////////////////////////////////////////////////////////////////
46 /// _FocusManagerImpl class Lifecycle
47 _FocusManagerImpl* _FocusManagerImpl::__pInstance = null;
48
49 _FocusManagerImpl::_FocusManagerImpl(void)
50 {
51         result r = _UiEventManager::GetInstance()->AddPostKeyEventListener(*this);
52         SysTryReturnVoidResult(NID_UI,  r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
53         
54         r = _UiEventManager::GetInstance()->AddTouchEventListener(*this);
55         SysTryReturnVoidResult(NID_UI,  r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
56 }
57
58
59 _FocusManagerImpl::~_FocusManagerImpl(void)
60 {
61         // NOTHING
62 }
63
64 void
65 _FocusManagerImpl::Initialize(void)
66 {
67         static pthread_once_t once_block = PTHREAD_ONCE_INIT;
68
69         if (__pInstance == null)
70         {
71                 pthread_once(&once_block, InitializeInstance);
72         }
73 }
74
75 _FocusManagerImpl*
76 _FocusManagerImpl::GetInstance(void)
77 {
78         return __pInstance;
79 }
80
81 void
82 _FocusManagerImpl::InitializeInstance(void)
83 {
84         ClearLastResult();
85
86         if (__pInstance == null)
87         {
88                 __pInstance = new (std::nothrow) _FocusManagerImpl;
89                 SysTryReturnVoidResult(NID_UI, __pInstance != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
90         }
91 }
92
93 void
94 _FocusManagerImpl::ReleaseInstance(void)
95 {
96         if (__pInstance)
97         {
98                 delete __pInstance;
99                 __pInstance = null;
100         }
101 }
102
103 ////////////////////////////////////////////////////////////////////////////////
104 /// _FocusManagerImpl class Operation
105
106 _ControlImpl*
107 _FocusManagerImpl::GetCurrentFocusOwner(void) const
108 {
109         _Control* pFocus = _ControlManager::GetInstance()->GetFocusedControl();
110         if(pFocus == null)
111         {
112                 return null;
113         }
114
115         _ControlImpl* pFocusImpl = static_cast <_ControlImpl*>(pFocus->GetUserData());
116         SysAssert(pFocusImpl);
117
118         return pFocusImpl;
119 }
120
121
122 _WindowImpl*
123 _FocusManagerImpl::GetCurrentFocusedWindow(void) const
124 {
125         _Control* pFocus = _ControlManager::GetInstance()->GetFocusedControl();
126         if(pFocus == null)
127         {
128                 return null;
129         }
130         _Window* pWindow = pFocus->GetRootWindow();
131         SysAssert(pWindow);
132
133         _WindowImpl* pWindowImpl = static_cast <_WindowImpl*>(static_cast <_ControlImpl*>(pWindow->GetUserData()));
134         SysAssert(pWindowImpl);
135
136         return pWindowImpl;
137 }
138
139 int
140 _FocusManagerImpl::GetNextIndex(int currentIndex, FocusDirection focusDirection, const IListT<_Control*>* pFocusControlList) const
141 {
142         int nextIndex = currentIndex;
143         if (focusDirection == FOCUS_DIRECTION_DOWNWARD)
144         {
145                 ++nextIndex;
146                 if (nextIndex == pFocusControlList->GetCount())
147                 {
148                         nextIndex = 0;
149                 }
150         }
151         else
152         {
153                 --nextIndex;
154                 if (nextIndex  < 0)
155                 {
156                         nextIndex = pFocusControlList->GetCount() - 1;
157                 }
158         }
159         return nextIndex;
160
161
162 }
163
164 bool 
165 _FocusManagerImpl::IsFocusable(_Control* pControl) const
166 {
167         bool isFocusalbe = pControl->IsFocusable();
168         bool enableState = pControl->GetEnableState();
169         bool visibleState = pControl->GetVisibleState();        
170         if (enableState  && visibleState  && isFocusalbe)
171         {
172                 return true;
173         }
174         return false;
175 }
176
177 void
178 _FocusManagerImpl::StartFocusTraversal(_Control* pControl, FocusDirection focusDirection)
179 {
180         bool focusMode = pControl->IsFocusModeStateEnabled();
181         if (focusMode == false && pControl->IsFocused())
182         {
183                 if (IsFocusable(pControl))
184                 {
185                         __pCurrentFocusUiControl = pControl;
186                         pControl->DrawFocus();
187                         pControl->SetFocusModeStateEnabled(true);
188                         return;
189                 }
190         }
191
192         if (focusDirection == FOCUS_DIRECTION_DOWNWARD)
193         {
194                 _Control* pFocusControl =  pControl->GetNextFocus();
195                 if (pFocusControl)
196                 {
197                         pFocusControl->SetFocused();
198                         pFocusControl->DrawFocus();
199                         return;
200                 }
201         }
202         else
203         {
204                 _Control* pFocusControl =  pControl->GetPreviousFocus();
205                 if (pFocusControl)
206                 {
207                         pFocusControl->SetFocused();
208                         pFocusControl->DrawFocus();
209                         return;
210                 }
211         }
212
213         IListT<_Control*>* pFocusControlList =  null;
214         _Window* pTop = pControl->GetRootWindow();
215         if (pTop)
216         {
217                 _Frame* pFrame = dynamic_cast<_Frame*>(pTop);
218                 if (pFrame)
219                 {
220                         _Form* pForm = pFrame->GetCurrentForm();
221                         pFocusControlList = pForm->GetFocusList();
222                 }
223                 else
224                 {
225                         pFocusControlList = pTop->GetFocusList();
226                 }
227         }
228
229         if (pFocusControlList)
230         {
231                 unique_ptr<IEnumeratorT<_Control*> > pEnum (pFocusControlList->GetEnumeratorN());
232                 SysTryReturnVoidResult(NID_UI_CTRL, pEnum, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
233                 int index = 0;
234                 bool findNextFocusControl = false;
235                 _Control* pNextFocusControl = null;
236                 while (pEnum->MoveNext() == E_SUCCESS)
237                 {
238                         _Control* pEnumeratorControl = null;
239                         pEnum->GetCurrent(pEnumeratorControl);
240
241                         //Find current focused control
242                         if (pControl == pEnumeratorControl)
243                         {
244                         //Find next focusable control.
245                         index = GetNextIndex(index, focusDirection, pFocusControlList);
246                         
247                                 while (pFocusControlList->GetAt(index, pNextFocusControl) == E_SUCCESS)
248                                 {
249                                         if (IsFocusable(pNextFocusControl))
250                                         {
251                                                 if (pNextFocusControl != pControl)
252                                                 {
253                                                     pNextFocusControl->SetFocused();
254                                                     pNextFocusControl->SetFocusModeStateEnabled(true);
255                                                     pControl->SetFocusModeStateEnabled(false);
256                                                 }
257                                                 findNextFocusControl = true;
258                                                 break;
259                                         }
260                                         else
261                                         {
262                                                 index = GetNextIndex(index, focusDirection, pFocusControlList);
263                                         }
264                                 }
265                         }
266
267                         if (findNextFocusControl == true)
268                         {
269                                 break;
270                         }
271
272                         index ++;
273                 }
274
275                 __pCurrentFocusUiControl = pNextFocusControl;
276                 if (pNextFocusControl && findNextFocusControl == true)
277                 {
278                         _Control* pParentControl =  pNextFocusControl->GetParent();
279                         if (pParentControl)
280                         {
281                                 pParentControl->OnChildControlFocusMoved(*pNextFocusControl);
282                         }
283                         pNextFocusControl->DrawFocus();
284                 }
285         }
286 }
287
288 bool
289 _FocusManagerImpl::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
290 {
291         _KeyCode keyCode = keyInfo.GetKeyCode();
292
293         if(keyCode == _KEY_TAB)
294         {
295                 FocusDirection focusDirection = FOCUS_DIRECTION_DOWNWARD;
296                 if (keyInfo.GetKeyModifier() & _KEY_MODIFIER_SHIFT)
297                 {
298                         focusDirection = FOCUS_DIRECTION_UPWARD;
299                 }
300
301                 _Control* pControl = const_cast<_Control*> (&source);
302                 StartFocusTraversal(pControl, focusDirection);
303         }
304         return false;
305 }
306 bool
307 _FocusManagerImpl::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
308 {
309         return false;
310 }
311
312 bool 
313 _FocusManagerImpl::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
314 {       
315         if (__pCurrentFocusUiControl)
316         {
317                 __pCurrentFocusUiControl->RemoveFocusRing();
318                 __pCurrentFocusUiControl->SetFocusModeStateEnabled(false);
319                 __pCurrentFocusUiControl = null;
320         }
321         return false;
322 }
323
324 bool 
325 _FocusManagerImpl::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo) 
326 {
327         return false;
328 }
329
330 bool
331 _FocusManagerImpl:: OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
332 {       
333         return false;
334 }
335
336 bool 
337 _FocusManagerImpl::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
338 {       
339         return false;
340 }
341 } } //Tizen::Ui