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