Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_OptionMenu.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  * @file                FUiCtrl_OptionMenu.cpp
19  * @brief               This is the implementation file for the _OptionMenu class.
20  */
21
22 #include <FBaseColIEnumeratorT.h>
23
24 #include "FUiCtrl_OptionMenu.h"
25 #include "FUiCtrl_OptionMenuPresenter.h"
26 #include "FUiCtrl_ActionEvent.h"
27 #include "FUiCtrl_ContextMenu.h"
28 #include "FUiCtrl_Frame.h"
29 #include "FUiCtrl_Form.h"
30 #include "FUiAnim_VisualElement.h"
31 #include "FUi_AccessibilityContainer.h"
32 #include "FUi_AccessibilityElement.h"
33 #include "FUi_ResourceManager.h"
34
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Collection;
37 using namespace Tizen::Base::Runtime;
38 using namespace Tizen::Graphics;
39 using namespace Tizen::Ui;
40
41 namespace Tizen { namespace Ui { namespace Controls
42 {
43
44 _OptionMenu::_OptionMenu(void)
45         : _Window()
46         , __pOptionMenuPresenter(null)
47         , __pActionEvent(null)
48         , __pSubMenu(null)
49         , __subMenuIndex(-1)
50 {
51 }
52
53 _OptionMenu::~_OptionMenu(void)
54 {
55         delete __pOptionMenuPresenter;
56         __pOptionMenuPresenter = null;
57
58         if (__pActionEvent != null)
59         {
60                 delete __pActionEvent;
61                 __pActionEvent = null;
62         }
63
64         if (__pSubMenu != null)
65         {
66                 __pSubMenu->Close();
67                 delete __pSubMenu;
68                 __pSubMenu = null;
69         }
70
71         RemoveAllAccessibilityElement();
72 }
73
74 _OptionMenu*
75 _OptionMenu::CreateOptionMenuN(void)
76 {
77         _OptionMenu* pOptionMenu = new (std::nothrow) _OptionMenu;
78         SysTryReturn(NID_UI_CTRL, (pOptionMenu != null), null, E_OUT_OF_MEMORY,
79                                  "[E_OUT_OF_MEMORY] Memory allocation failed.");
80
81         result r = GetLastResult();
82         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), null, r, "[%s] Propagating.", GetErrorMessage(r));
83
84 #if defined(MULTI_WINDOW)
85         r = pOptionMenu->CreateRootVisualElement();
86         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
87 #endif
88
89         pOptionMenu->AcquireHandle();
90
91         SysTryCatch(NID_UI_CTRL, (pOptionMenu->GetVisualElement() != null), , E_SYSTEM,
92                             "[E_SYSTEM] A system error has occurred. Failed to get _VisualElement instance.");
93
94         pOptionMenu->__pOptionMenuPresenter = _OptionMenuPresenter::CreateInstanceN(*pOptionMenu);
95         r = GetLastResult();
96         SysTryCatch(NID_UI_CTRL, (pOptionMenu->__pOptionMenuPresenter != null), , r,
97                             "[%s] Propagating.", GetErrorMessage(r));
98
99         r = pOptionMenu->__pOptionMenuPresenter->InitializeTextObject();
100         SysTryCatch(NID_UI_CTRL, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
101
102         r = pOptionMenu->__pOptionMenuPresenter->InitializeVisualElement();
103         SysTryCatch(NID_UI_CTRL, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
104
105         pOptionMenu->__pActionEvent = _ActionEvent::CreateInstanceN(*pOptionMenu);
106         r = GetLastResult();
107         SysTryCatch(NID_UI_CTRL, (pOptionMenu->__pActionEvent != null), , r,
108                             "[%s] Propagating.", GetErrorMessage(r));
109
110         // Set alpha merge to VisualElement
111         pOptionMenu->GetVisualElement()->SetSurfaceOpaque(false);
112         pOptionMenu->SetBackgroundColor(Color());
113
114         pOptionMenu->SetMovable(false);
115         pOptionMenu->SetResizable(false);
116
117         if (pOptionMenu->GetAccessibilityContainer() != null)
118         {
119                 pOptionMenu->GetAccessibilityContainer()->Activate(true);
120         }
121
122         return pOptionMenu;
123 CATCH:
124         delete pOptionMenu;
125         return null;
126 }
127
128 result
129 _OptionMenu::AddActionEventListener(const _IActionEventListener& listener)
130 {
131         return __pActionEvent->AddListener(listener);
132 }
133
134 result
135 _OptionMenu::RemoveActionEventListener(const _IActionEventListener& listener)
136 {
137         return __pActionEvent->RemoveListener(listener);
138 }
139
140 result
141 _OptionMenu::FireActionEvent(int actionId)
142 {
143         IEventArg* pArg = _ActionEvent::CreateActionEventArgN(actionId);
144         result r = GetLastResult();
145         SysTryReturn(NID_UI_CTRL, (pArg != null), r, r, "[%s] Propagating.", GetErrorMessage(r));
146
147         r = __pActionEvent->Fire(*pArg);
148
149         return r;
150 }
151
152 result
153 _OptionMenu::AddItem(const String& text, int actionId)
154 {
155         result r = __pOptionMenuPresenter->AddItem(text, actionId);
156
157         if (likely(!(_AccessibilityManager::IsActivated())))
158         {
159                 return r;
160         }
161
162         if (r == E_SUCCESS)
163         {
164                 _AccessibilityContainer* pContainer = GetAccessibilityContainer();
165                 if (pContainer != null)
166                 {
167                         _AccessibilityElement* pElement = new (std::nothrow) _AccessibilityElement(true);
168                         if (pElement != null)
169                         {
170                                 pElement->SetLabel(text);
171                                 pElement->SetTrait(ACCESSIBILITY_TRAITS_BUTTON);
172                                 pElement->SetHint(L"Double tap to select");
173 //                              pElement->SetTrait(ACCESSIBILITY_TRAITS_OPTIONMENU);
174                                 pContainer->AddElement(*pElement);
175                                 __accessibilityElements.Add(pElement);
176                                 SetBoundsAllAccessibilityElement();
177                         }
178                 }
179         }
180
181         return r;
182 }
183
184 result
185 _OptionMenu::InsertItemAt(int mainIndex, const String& text, int actionId)
186 {
187         result r = __pOptionMenuPresenter->InsertItemAt(mainIndex, text, actionId);
188
189         if (likely(!(_AccessibilityManager::IsActivated())))
190         {
191                 return r;
192         }
193
194         if (r == E_SUCCESS)
195         {
196                 _AccessibilityContainer* pContainer = GetAccessibilityContainer();
197                 if (pContainer != null)
198                 {
199                         _AccessibilityElement* pElement = new (std::nothrow) _AccessibilityElement(true);
200                         if (pElement != null)
201                         {
202                                 pElement->SetLabel(text);
203                                 pElement->SetTrait(ACCESSIBILITY_TRAITS_BUTTON);
204                                 pElement->SetHint(L"Double tap to select");
205 //                              pElement->SetTrait(ACCESSIBILITY_TRAITS_OPTIONMENU);
206                                 pContainer->InsertElement(*pElement, mainIndex);
207                                 __accessibilityElements.InsertAt(pElement, mainIndex);
208                                 SetBoundsAllAccessibilityElement();
209                         }
210                 }
211         }
212
213         return r;
214 }
215
216 result
217 _OptionMenu::SetItemAt(int mainIndex, const String& text, int actionId)
218 {
219         result r = __pOptionMenuPresenter->SetItemAt(mainIndex, text, actionId);
220
221         if (likely(!(_AccessibilityManager::IsActivated())))
222         {
223                 return r;
224         }
225
226         if (r == E_SUCCESS)
227         {
228                 _AccessibilityElement* pElement = GetAccessibilityElement(mainIndex);
229                 if (pElement != null)
230                 {
231                         pElement->SetLabel(text);
232                 }
233         }
234
235         return r;
236 }
237
238 result
239 _OptionMenu::RemoveItemAt(int mainIndex)
240 {
241         result r = __pOptionMenuPresenter->RemoveItemAt(mainIndex);
242
243         if (likely(!(_AccessibilityManager::IsActivated())))
244         {
245                 return r;
246         }
247
248         if (r == E_SUCCESS)
249         {
250                 _AccessibilityContainer* pContainer = GetAccessibilityContainer();
251                 if (pContainer != null)
252                 {
253                         _AccessibilityElement* pElement = GetAccessibilityElement(mainIndex);
254                         if (pElement != null)
255                         {
256                                 pContainer->RemoveElement(*pElement);
257                                 __accessibilityElements.RemoveAt(mainIndex);
258                                 SetBoundsAllAccessibilityElement();
259                         }
260                 }
261         }
262
263         return r;
264 }
265
266 int
267 _OptionMenu::GetItemCount(void) const
268 {
269         return __pOptionMenuPresenter->GetItemCount();
270 }
271
272 int
273 _OptionMenu::GetItemIndexFromActionId(int actionId) const
274 {
275         return __pOptionMenuPresenter->GetItemIndexFromActionId(actionId);
276 }
277
278 int
279 _OptionMenu::GetItemActionIdAt(int mainIndex) const
280 {
281         return __pOptionMenuPresenter->GetItemActionIdAt(mainIndex);
282 }
283
284 result
285 _OptionMenu::AddSubItem(int mainIndex, const String& text, int actionId)
286 {
287         result r = __pOptionMenuPresenter->AddSubItem(mainIndex, text, actionId);
288         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), r, r, "[%s] Propagating.", GetErrorMessage(r));
289
290         if (__pSubMenu != null && mainIndex == __subMenuIndex)
291         {
292                 __pSubMenu->AddItem(text, actionId, null, null, null);
293         }
294         return E_SUCCESS;
295 }
296
297 result
298 _OptionMenu::InsertSubItemAt(int mainIndex, int subIndex, const String& text, int actionId)
299 {
300         result r = __pOptionMenuPresenter->InsertSubItemAt(mainIndex, subIndex, text, actionId);
301         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), r, r, "[%s] Propagating.", GetErrorMessage(r));
302
303         if (__pSubMenu != null && mainIndex == __subMenuIndex)
304         {
305                 __pSubMenu->InsertItem(subIndex, text, actionId, null, null, null);
306         }
307
308         return E_SUCCESS;
309 }
310
311 result
312 _OptionMenu::SetSubItemAt(int mainIndex, int subIndex, const String& text, int actionId)
313 {
314         result r = __pOptionMenuPresenter->SetSubItemAt(mainIndex, subIndex, text, actionId);
315         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), r, r, "[%s] Propagating.", GetErrorMessage(r));
316
317         if (__pSubMenu != null && mainIndex == __subMenuIndex)
318         {
319                 __pSubMenu->SetItem(subIndex, text, actionId, null, null, null);
320         }
321
322         return E_SUCCESS;
323 }
324
325 result
326 _OptionMenu::RemoveSubItemAt(int mainIndex, int subIndex)
327 {
328         result r = __pOptionMenuPresenter->RemoveSubItemAt(mainIndex, subIndex);
329         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), r, r, "[%s] Propagating.", GetErrorMessage(r));
330
331         if (__pSubMenu != null && mainIndex == __subMenuIndex)
332         {
333                 __pSubMenu->RemoveItemAt(subIndex);
334         }
335
336         return E_SUCCESS;
337 }
338
339 int
340 _OptionMenu::GetSubItemCount(int mainIndex) const
341 {
342         return __pOptionMenuPresenter->GetSubItemCount(mainIndex);
343 }
344
345 int
346 _OptionMenu::GetSubItemIndexFromActionId(int actionId) const
347 {
348         return __pOptionMenuPresenter->GetSubItemIndexFromActionId(actionId);
349 }
350
351 int
352 _OptionMenu::GetSubItemActionIdAt(int mainIndex, int subIndex) const
353 {
354         return __pOptionMenuPresenter->GetSubItemActionIdAt(mainIndex, subIndex);
355 }
356
357 bool
358 _OptionMenu::IsSubMenuShown(void) const
359 {
360         return (__pSubMenu != null) && __pSubMenu->IsAttached();
361 }
362
363 result
364 _OptionMenu::ShowSubMenu(int mainIndex, _OptionMenuItem& item)
365 {
366         if (__pSubMenu != null)
367         {
368                 DestroySubMenu();
369         }
370
371         int textSize = 0;
372         Font* pFont = __pOptionMenuPresenter->GetFont();
373         GET_SHAPE_CONFIG(OPTIONMENU::TEXT_SIZE, GetOrientation(), textSize);
374
375         Rectangle itemBounds = __pOptionMenuPresenter->GetItemBounds(mainIndex);
376         Point anchorPosition(GetBounds().x + itemBounds.x + itemBounds.width / 2,
377                                                  GetBounds().y + itemBounds.y + itemBounds.height / 2 - textSize / 2);
378         __pSubMenu = _ContextMenu::CreateContextMenuN(anchorPosition,
379                                                                                                   CONTEXT_MENU_CORE_STYLE_LIST,
380                                                                                                   CONTEXT_MENU_CORE_ALIGN_UP);
381         if (__pSubMenu == null)
382         {
383                 return GetLastResult();
384         }
385
386         if (__pSubMenu->GetOwner() == null)
387         {
388                 _Frame* pFrame = dynamic_cast<_Frame*>(_ControlManager::GetInstance()->GetCurrentFrame());
389                 SysTryReturn(NID_UI_CTRL, pFrame != null, E_SYSTEM,
390                                         E_SYSTEM, "[E_SYSTEM] This instance is not constructed.");
391
392                 _Form* pForm = pFrame->GetCurrentForm();
393                 if (pForm != null)
394                 {
395                         __pSubMenu->SetOwner(pForm);
396                 }
397                 else
398                 {
399                         __pSubMenu->SetOwner(pFrame);
400                 }
401         }
402
403         __pSubMenu->Initialize();
404         __pSubMenu->AddActionEventListener(*this);
405
406         _OptionMenuItem* pSubItem = null;
407         int subItemCount = item.GetSubItemCount();
408         for (int subIndex = 0; subIndex < subItemCount; subIndex++)
409         {
410                 pSubItem = item.GetSubItem(subIndex);
411                 if (pSubItem != null)
412                 {
413                         __pSubMenu->AddItem(pSubItem->GetText(), pSubItem->GetActionId(), null, null, null);
414                 }
415         }
416
417         if (pFont != null)
418         {
419                 __pSubMenu->SetFont(pFont->GetFaceName());
420         }
421
422         __pSubMenu->Open();
423         SetTouchCapture();
424         __subMenuIndex = mainIndex;
425
426         return E_SUCCESS;
427 }
428
429 result
430 _OptionMenu::DestroySubMenu(void)
431 {
432         if (__pSubMenu == null)
433         {
434                 return E_SYSTEM;
435         }
436
437         __pSubMenu->Close();
438         delete __pSubMenu;
439         __pSubMenu = null;
440         __subMenuIndex = -1;
441
442         return E_SUCCESS;
443 }
444
445 _AccessibilityElement*
446 _OptionMenu::GetAccessibilityElement(int mainIndex)
447 {
448         if (likely(!(_AccessibilityManager::IsActivated())))
449         {
450                 return null;
451         }
452
453         _AccessibilityElement* pElement = null;
454         result r = E_SUCCESS;
455
456         if(likely(!(_AccessibilityManager::IsActivated())))
457         {
458                 return null;
459         }
460
461         r = __accessibilityElements.GetAt(mainIndex,pElement);
462         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), null, r, "[%s] Propagating.", GetErrorMessage(r));
463         return pElement;
464 }
465
466 void
467 _OptionMenu::OnDraw()
468 {
469         __pOptionMenuPresenter->Draw();
470 }
471
472 void
473 _OptionMenu::OnChangeLayout(_ControlOrientation orientation)
474 {
475         __pOptionMenuPresenter->OnChangeLayout(orientation);
476 }
477
478 void
479 _OptionMenu::OnBoundsChanged(void)
480 {
481         SetBoundsAllAccessibilityElement();
482 }
483
484 result
485 _OptionMenu::OnAttachingToMainTree(const _Control* pParent)
486 {
487         result r = __pOptionMenuPresenter->OnAttachingToMainTree(pParent);
488         if (r != E_SUCCESS)
489         {
490                 return r;
491         }
492
493         return _Window::OnAttachingToMainTree(pParent);
494 }
495
496 result
497 _OptionMenu::OnAttachedToMainTree(void)
498 {
499         __pOptionMenuPresenter->OnAttachedToMainTree();
500         return E_SUCCESS;
501 }
502
503 result
504 _OptionMenu::OnDetachingFromMainTree(void)
505 {
506         __pOptionMenuPresenter->OnDetachingFromMainTree();
507
508         return _Window::OnDetachingFromMainTree();
509 }
510
511 void
512 _OptionMenu::OnVisibleStateChanged(void)
513 {
514 #if defined(MULTI_WINDOW)
515         _Window::OnVisibleStateChanged();
516 #endif
517
518         __pOptionMenuPresenter->OnVisibleStateChanged();
519 }
520
521 void
522 _OptionMenu::OnActivated(void)
523 {
524         _Window::OnActivated();
525
526         if (GetOwner() != null)
527         {
528                 ChangeLayout(GetOwner()->GetOrientation());
529         }
530         else
531         {
532                 ChangeLayout(_ControlManager::GetInstance()->GetOrientation());
533         }
534
535         if (__pOptionMenuPresenter != null)
536         {
537                 __pOptionMenuPresenter->CalculateBounds();
538
539                 __pOptionMenuPresenter->PrepareAnimation();
540                 __pOptionMenuPresenter->SetOptionMenuVisibility(true);
541         }
542
543         SetTouchCapture();
544 }
545
546 void
547 _OptionMenu::OnDeactivated(void)
548 {
549         ReleaseTouchCapture();
550         _Window::OnDeactivated();
551 }
552
553 void
554 _OptionMenu::OnFontChanged(Font* pFont)
555 {
556         __pOptionMenuPresenter->OnFontChanged(pFont);
557         return;
558 }
559
560 void
561 _OptionMenu::OnFontInfoRequested(unsigned long& style, int& size)
562 {
563         __pOptionMenuPresenter->OnFontInfoRequested(style, size);
564         return;
565 }
566
567 bool
568 _OptionMenu::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
569 {
570         return __pOptionMenuPresenter->OnTouchPressed(source, touchinfo);
571 }
572
573 bool
574 _OptionMenu::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
575 {
576         return __pOptionMenuPresenter->OnTouchReleased(source, touchinfo);
577 }
578
579 bool
580 _OptionMenu::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
581 {
582         return __pOptionMenuPresenter->OnTouchMoved(source, touchinfo);
583 }
584
585 bool
586 _OptionMenu::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
587 {
588         return __pOptionMenuPresenter->OnTouchCanceled(source, touchinfo);
589 }
590
591 void
592 _OptionMenu::OnActionPerformed(const _Control& source, int actionId)
593 {
594         __pOptionMenuPresenter->OnActionPerformed(source, actionId);
595 }
596
597 void
598 _OptionMenu::SetBoundsAllAccessibilityElement(void)
599 {
600         if (likely(!(_AccessibilityManager::IsActivated())))
601         {
602                 return;
603         }
604
605         _AccessibilityElement* pElement = null;
606         IEnumeratorT<_AccessibilityElement*>* pEnumerator = __accessibilityElements.GetEnumeratorN();
607         int index = 0;
608         while (pEnumerator->MoveNext() == E_SUCCESS)
609         {
610                 if (pEnumerator->GetCurrent(pElement) == E_SUCCESS)
611                 {
612                         pElement->SetBounds(__pOptionMenuPresenter->GetItemBounds(index));
613                 }
614                 index++;
615         }
616         delete pEnumerator;
617 }
618
619 void
620 _OptionMenu::RemoveAllAccessibilityElement(void)
621 {
622         if (likely(!(_AccessibilityManager::IsActivated())))
623         {
624                 return;
625         }
626
627         _AccessibilityElement* pElement = null;
628         while (__accessibilityElements.GetCount() > 0)
629         {
630                 if ((__accessibilityElements.GetAt(0, pElement)) == E_SUCCESS)
631                 {
632                         __accessibilityElements.RemoveAt(0);
633                         pElement->GetParent()->RemoveElement(*pElement);
634                 }
635                 else
636                 {
637                         __accessibilityElements.RemoveAt(0);
638                 }
639         }
640 }
641
642 }}} // Tizen::Ui::Controls