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