modify license, permission and remove ^M char
[platform/framework/native/uifw.git] / src / ui / FUi_AccessibilityContainer.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 #include <FBaseSysLog.h>
19 #include <FGrpFloatRectangle.h>
20 #include "FUi_Control.h"
21 #include "FUi_AccessibilityElement.h"
22 #include "FUi_AccessibilityElementImpl.h"
23 #include "FUi_AccessibilityContainer.h"
24 #include "FUi_AccessibilityManager.h"
25 #include "FUi_IAccessibilityListener.h"
26 #include "FUi_IAccessibilityFocusHandler.h"
27
28 using namespace Tizen::Base;
29 using namespace Tizen::Base::Collection;
30 using namespace Tizen::Graphics;
31
32 namespace Tizen { namespace Ui
33 {
34
35 template <class T>
36 class _AccessibilityItemComparer
37         : public Tizen::Base::Collection::IComparerT <T>
38 {
39 public:
40         _AccessibilityItemComparer(void)
41         {
42         }
43         virtual ~_AccessibilityItemComparer(void)
44         {
45         }
46         virtual result Compare(const T& obj1, const T& obj2, int& cmp) const
47         {
48                 Tizen::Graphics::FloatRectangle rect1= obj1->GetAbsoluteBounds();
49                 Tizen::Graphics::FloatRectangle rect2= obj2->GetAbsoluteBounds();
50
51                 if(rect1.y > rect2.y)
52                 {
53                         cmp = 1;
54                         return E_SUCCESS;
55                 }
56                 else if(rect1.y < rect2.y)
57                 {
58                         cmp = -1;
59                         return E_SUCCESS;
60                 }
61                 else
62                 {
63                         if(rect1.x > rect2.x)
64                         {
65                                 cmp = 1;
66                                 return E_SUCCESS;
67                         }
68                         else if(rect1.x < rect2.x)
69                         {
70                                 cmp = -1;
71                                 return E_SUCCESS;
72                         }
73                         else
74                         {
75                                 cmp = 0;
76                                 return E_SUCCESS;
77                         }
78                 }
79         }
80 }; //class _AccessibilityComparer
81
82 _AccessibilityContainer::_AccessibilityContainer(const _Control& owner)
83         : __pOwner(null)
84         , __pParent(null)
85         , __currentElementIndex(-1)
86         , __level(ACCESSIBILITY_PRIORITY_NORMAL)
87         , __activated(false)
88         , __pListener(null)
89         , __enableState(true)
90         , __pFocusHandler(null)
91 {
92         __pOwner = &(const_cast<_Control&>(owner));
93         __handle = _AccessibilityManager::GetInstance()->Register(this);
94 }
95
96 _AccessibilityContainer::~_AccessibilityContainer(void)
97 {
98         RemoveAllElement();
99         _AccessibilityManager::GetInstance()->RemoveContainer(*this);
100         if(__handle.IsValid())
101         {
102                 _AccessibilityManager::GetInstance()->Unregister(__handle);
103         }
104 }
105
106 _Control&
107 _AccessibilityContainer::GetOwner(void)
108 {
109         return *__pOwner;
110 }
111
112 const _Control&
113 _AccessibilityContainer::GetOwner(void) const
114 {
115         return *__pOwner;
116 }
117
118 result
119 _AccessibilityContainer::AddChildContainer(const _AccessibilityContainer& child)
120 {
121         if(child.GetParent() == this)
122         {
123                 return E_SUCCESS;
124         }
125
126         result r = E_SYSTEM;
127         _AccessibilityContainer* _child = &const_cast<_AccessibilityContainer&>(child);
128         _child->SetParent(*this);
129         __childContainerList.Add(_child);
130         return r;
131 }
132
133 result
134 _AccessibilityContainer::RemoveChildContainer(const _AccessibilityContainer& child)
135 {
136         return __childContainerList.Remove(&const_cast<_AccessibilityContainer&>(child));
137 }
138
139 const LinkedListT<_AccessibilityContainer*>*
140 _AccessibilityContainer::GetChildContainerList(void) const
141 {
142         return &__childContainerList;
143 }
144
145 result
146 _AccessibilityContainer::AddElement(const _AccessibilityElement& element)
147 {
148         const_cast<_AccessibilityElement&>(element).SetParent(*this);
149         if(__elementList.Contains(&const_cast<_AccessibilityElement&>(element)))
150         {
151                 return E_SUCCESS;
152         }
153         return __elementList.Add(&const_cast<_AccessibilityElement&>(element));
154 }
155
156 result
157 _AccessibilityContainer::AddElements(const IListT<_AccessibilityElement*>& elementList)
158 {
159         _AccessibilityElement* pElement = null;
160         int count = elementList.GetCount();
161         for (int i = 0; i < count ; i++)
162         {
163                 if(elementList.GetAt(i, pElement) == E_SUCCESS)
164                 {
165                         pElement->SetParent(*this);
166                 }
167         }
168         return __elementList.AddItems(elementList);
169 }
170
171 result
172 _AccessibilityContainer::InsertElement(const _AccessibilityElement& element, int index)
173 {
174         const_cast<_AccessibilityElement&>(element).SetParent(*this);
175         return __elementList.InsertAt(&const_cast<_AccessibilityElement&>(element), index);
176 }
177
178 result
179 _AccessibilityContainer::RemoveElement(const _AccessibilityElement& element)
180 {
181         _AccessibilityElement* pElement = &const_cast<_AccessibilityElement&>(element);
182         result r = __elementList.Remove(pElement);
183         if (r == E_SUCCESS)
184         {
185                 delete pElement;
186         }
187         return r;
188 }
189
190 result
191 _AccessibilityContainer::RemoveAllElement()
192 {
193         result r = E_SUCCESS;
194         _AccessibilityElement* pElement = null;
195         int count = __elementList.GetCount();
196         for (int i = 0; i < count ;i++)
197         {
198                 r = __elementList.GetAt(i, pElement);
199                 if (r == E_SUCCESS)
200                 {
201                         delete pElement;
202                         pElement = null;
203                 }
204         }
205         __elementList.RemoveAll();
206         return E_SUCCESS;
207 }
208
209 void
210 _AccessibilityContainer::SortElements(void)
211 {
212         _AccessibilityItemComparer<_AccessibilityElement*> comparer;
213         __elementList.Sort(comparer);
214 }
215
216 _AccessibilityElement*
217 _AccessibilityContainer::GetChildElement(int index) const
218 {
219         int count = __elementList.GetCount();
220         if (count == 0 ||index > count - 1)
221         {
222                 return null;
223         }
224         _AccessibilityElement* pElement = null;
225         __elementList.GetAt(index, pElement);
226         if (pElement->IsActivated())
227         {
228                 return pElement;
229         }
230         else
231         {
232                 return false;
233         }
234 }
235
236 _AccessibilityElement*
237 _AccessibilityContainer::GetChildElement(const String& name) const
238 {
239         int count = __elementList.GetCount();
240         _AccessibilityElement* pElement = null;
241         result r = E_SUCCESS;
242         for (int i = count -1 ; i >= 0 ; i--)
243         {
244                 r = __elementList.GetAt(i, pElement);
245                 if (r == E_SUCCESS && pElement->GetName() == name)
246                 {
247                         if (pElement->IsActivated())
248                         {
249                                 return pElement;
250                         }
251                         else
252                         {
253                                 return false;
254                         }
255                 }
256         }
257         if (__childContainerList.GetCount() > 0)
258         {
259                 IEnumeratorT<_AccessibilityContainer*>* pEnumerator = __childContainerList.GetEnumeratorN();
260                 while (pEnumerator->MoveNext() == E_SUCCESS)
261                 {
262                         _AccessibilityContainer* pContainer = null;
263                         pEnumerator->GetCurrent(pContainer);
264                         _AccessibilityElement* pElement = pContainer->GetChildElement(name);
265                         if (pElement != null)
266                         {
267                                 if (pElement->IsActivated())
268                                 {
269                                         return pElement;
270                                 }
271                                 else
272                                 {
273                                         return false;
274                                 }
275                                 return pElement;
276                         }
277                 }
278         }
279         return null;
280 }
281
282 void
283 _AccessibilityContainer::GetElements(IListT<_AccessibilityElement*>& list) const
284 {
285         int count = __elementList.GetCount();
286         result r = E_SUCCESS;
287         _AccessibilityElement* pElement = null;
288
289         for (int i = 0; i < count; i++)
290         {
291                 r = __elementList.GetAt(i, pElement);
292                 SysTryReturn(NID_UI, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] System Error.");
293                 SysTryReturn(NID_UI, pElement, , E_SYSTEM, "[E_SYSTEM] System Error.");
294                 if(!list.Contains(pElement) && pElement->IsActivated())
295                 {
296                         list.Add(pElement);
297                 }
298                 pElement = null;
299         }
300 }
301
302 IListT <_AccessibilityElement*>*
303 _AccessibilityContainer::GetElementsN(void) const
304 {
305         LinkedListT<_AccessibilityElement*>* pList = new (std::nothrow) LinkedListT<_AccessibilityElement*>;
306         GetElements(*pList);
307         return pList;
308 }
309
310 _AccessibilityElement*
311 _AccessibilityContainer::Hit(const Point& point) const
312 {
313         if (!__activated)
314         {
315                 return null;
316         }
317
318         _AccessibilityElement* pElement = null;
319         int count = __elementList.GetCount();
320         result r = E_SUCCESS;
321
322         for (int i = count -1 ; i >= 0   ; i--)
323         {
324                 r = __elementList.GetAt(i, pElement);
325                 SysTryReturn(NID_UI, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] System Error.");
326                 SysTryReturn(NID_UI, pElement, null, E_SYSTEM, "[E_SYSTEM] System Error.");
327
328                 if (!(pElement->IsActivated()))
329                         continue;
330
331                 FloatRectangle rect = pElement->GetAbsoluteBounds();
332
333                 if (rect.x < point.x && rect.y < point.y
334                         && rect.x + rect.width > point.x
335                         && rect.y + rect.height > point.y)
336                 {
337                         return pElement;
338                 }
339         }
340         return null;
341 }
342
343 result
344 _AccessibilityContainer::MoveElement(const _AccessibilityElement* pPreviousElement, const _AccessibilityElement& element)
345 {
346         _AccessibilityElement* pElement = GetChildElement(element.GetName());
347         if (pElement == null)
348         {
349                 return E_OBJ_NOT_FOUND;
350         }
351
352         if (pPreviousElement == null)
353         {
354                 __elementList.Remove(pElement);
355                 __elementList.InsertAt(pElement, 0);
356         }
357         else
358         {
359                 _AccessibilityElement* _pPreviousElement = GetChildElement(pPreviousElement->GetName());
360                 if (_pPreviousElement == null)
361                 {
362                         return E_OBJ_NOT_FOUND;
363                 }
364                 __elementList.Remove(pElement);
365                 int indexOfPreviousItem = 0;
366                 __elementList.IndexOf(_pPreviousElement, indexOfPreviousItem);
367                 __elementList.InsertAt(pElement, indexOfPreviousItem+1);
368         }
369 //      SortElements();
370         return E_SUCCESS;
371 }
372 void
373 _AccessibilityContainer::SetFocusHandler(_IAccessibilityFocusHandler* pHandler)
374 {
375         __pFocusHandler = pHandler;
376 }
377 bool
378 _AccessibilityContainer::IsFocusManaged(void)
379 {
380         return (__pFocusHandler != null? true:false);
381 }
382 bool
383 _AccessibilityContainer::MoveFocus(_AccessibilityFocusDirection direction)
384 {
385         if(!__pFocusHandler)
386         {
387                 return false;
388         }
389         return __pFocusHandler->OnMoveFocus(direction);
390 }
391
392 bool
393 _AccessibilityContainer::MoveFocus(const Tizen::Graphics::Point& point)
394 {
395         if(__pFocusHandler)
396         {
397                 return __pFocusHandler->OnMoveFocus(point);
398         }
399         else
400         {
401                 _AccessibilityElement* pElement = Hit(point);
402                 if(pElement == null)
403                 {
404                         return false;
405                 }
406
407                 int index = -1;
408                 if (__elementList.IndexOf(pElement, index) != E_SUCCESS)
409                 {
410                         return false;
411                 }
412                 else
413                 {
414                         __currentElementIndex = index;
415                 }
416                 return true;
417         }
418 }
419
420 void
421 _AccessibilityContainer::ResetFocus(void)
422 {
423         __currentElementIndex = -1;
424 }
425
426 void
427 _AccessibilityContainer::SetPriority(int level)
428 {
429         __level = level;
430 }
431
432 int
433 _AccessibilityContainer::GetPriority(void)
434 {
435         return __level;
436 }
437
438 bool
439 _AccessibilityContainer::SetParent(const _AccessibilityContainer& parent)
440 {
441         if (__pParent == null)
442         {
443                 __pParent = &const_cast<_AccessibilityContainer&>(parent);
444                 return true;
445         }
446         else
447         {
448                 return false;
449         }
450 }
451
452 _AccessibilityContainer*
453 _AccessibilityContainer::GetParent(void) const
454 {
455         return __pParent;
456 }
457
458 void
459 _AccessibilityContainer::SetCurrentFocusedElement(_AccessibilityElement*pElement)
460 {
461         if (pElement == null)
462         {
463                 __currentElementIndex = -1;
464                 return;
465         }
466
467         int index = 0;
468         result r = __elementList.IndexOf(pElement, 0, index);
469         if (r == E_SUCCESS)
470         {
471                 __currentElementIndex = index;
472         }
473         else
474         {
475                 __currentElementIndex = -1;
476         }
477 }
478 _AccessibilityElement*
479 _AccessibilityContainer::GetCurrentFocusedElement(void) const
480 {
481         if (__currentElementIndex < 0)
482         {
483                 return null;
484         }
485
486         _AccessibilityElement* pElement = null;
487         result r = E_SUCCESS;
488         r = __elementList.GetAt(__currentElementIndex,pElement);
489         if (r == E_SUCCESS)
490         {
491                 return pElement;
492         }
493         else
494         {
495                 return null;
496         }
497 }
498
499 void
500 _AccessibilityContainer::AddListener(const _IAccessibilityListener& listener)
501 {
502         __listenerList.Add(&const_cast<_IAccessibilityListener&>(listener));
503 }
504
505 Tizen::Base::Collection::IListT<_IAccessibilityListener*>*
506 _AccessibilityContainer::GetListenerListN(void) const
507 {
508         return __listenerList.GetItemsN(0,__listenerList.GetCount());
509 }
510
511 void
512 _AccessibilityContainer::RemoveListener(const _IAccessibilityListener& listener)
513 {
514         __listenerList.Remove(&const_cast<_IAccessibilityListener&>(listener));
515 }
516 void
517 _AccessibilityContainer::SetEnableState(bool enabledState)
518 {
519         __enableState = enabledState;
520 }
521 bool
522 _AccessibilityContainer::GetEnableState(void)
523 {
524         return __enableState;
525 }
526 void
527 _AccessibilityContainer::Activate(bool enable)
528 {
529         if (enable)
530         {
531                 _AccessibilityManager::GetInstance()->AddContainer(*this);
532         }
533         else
534         {
535                 _AccessibilityManager::GetInstance()->RemoveContainer(*this);
536         }
537         __activated = enable;
538 }
539
540 bool
541 _AccessibilityContainer::IsActivated(void) const
542 {
543         return __activated;
544 }
545
546 FloatRectangle
547 _AccessibilityContainer::GetAbsoluteBounds(void) const
548 {
549         return __pOwner->GetAbsoluteBoundsF();
550 }
551
552 void
553 _AccessibilityContainer::ReadingAll(void)
554 {
555         _AccessibilityElement* pElement = null;
556         int count = __elementList.GetCount();
557         result r = E_SUCCESS;
558
559         for (int i = count -1 ; i >= 0   ; i--)
560         {
561                 r = __elementList.GetAt(i, pElement);
562                 SysTryReturn(NID_UI, r == E_SUCCESS && pElement, , E_SYSTEM, "[E_SYSTEM] System Error.");
563
564                 if (!(pElement->IsActivated()))
565                         continue;
566
567                 _AccessibilityManager::GetInstance()->ReadElement(*pElement);
568         }
569 }
570
571 String
572 _AccessibilityContainer::GetCurrentGrammar(void) const
573 {
574         //todo//
575         return L"";
576 }
577
578 AccessibilityScreenReaderStatus
579 _AccessibilityContainer::GetStatus(void) const
580 {
581         //todo//
582         return ACCESSIBILITY_SCREEN_READER_STATUS_ERROR;
583 }
584 Tizen::Base::_HandleT <_AccessibilityContainer>
585 _AccessibilityContainer::GetHandle(void) const
586 {
587         return __handle;
588 }
589 }} //Tizen::Ui