Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_Frame.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_Frame.cpp
19  * @brief               This is the implementation file for the _Frame class.
20  */
21
22 #include <new>
23 #include <FBaseErrorDefine.h>
24 #include <FBaseInteger.h>
25 #include <FBaseSysLog.h>
26 #include "FUi_UiNotificationEvent.h"
27 #include "FUi_UiEventManager.h"
28 #include "FUi_ControlManager.h"
29 #include "FUi_EcoreEvasMgr.h"
30 #include "FUi_EcoreEvas.h"
31 #include "FUi_TouchManager.h"
32 #include "FUiCtrl_Frame.h"
33 #include "FUiCtrl_FramePresenter.h"
34 #include "FUiCtrl_FrameEvent.h"
35 #include "FUiCtrl_IFrameEventListener.h"
36 #include "FUiCtrl_IFormActivationChangeEventListener.h"
37 #include "FUiCtrl_Form.h"
38 #include "FUiAnim_VisualElement.h"
39 #include "FUiAnim_RootVisualElement.h"
40 #include "FUiAnim_EflLayer.h"
41
42 using namespace Tizen::Ui::Animations;
43 using namespace Tizen::Ui;
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Base::Runtime;
47 using namespace Tizen::Graphics;
48
49 namespace Tizen { namespace Ui { namespace Controls {
50
51 _Frame::_Frame(void)
52         : __pFramePresenter(null)
53         , __pFrameEvent(null)
54         , __floatingBounds(0, 0, 0, 0)
55         , __showMode(FRAME_SHOW_MODE_FULL_SCREEN)
56         , __restore(false)
57         , __activated(false)
58         , __pFormActivationChangeEventListener(null)
59 {
60         _FramePresenter* pPresenter = new (std::nothrow) _FramePresenter(*this);
61         SysTryReturnVoidResult(NID_UI_CTRL, pPresenter, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
62
63         Dimension screen = _ControlManager::GetInstance()->GetScreenSize();
64         __floatingBounds.width = screen.width;
65         __floatingBounds.height = screen.height;
66
67         __pFrameEvent = _FrameEvent::CreateInstanceN(*this);
68         SysTryCatch(NID_UI_CTRL, __pFrameEvent, , GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
69
70         SetPresenter(*pPresenter);
71         SetClipChildrenEnabled(false);
72
73         ClearLastResult();
74
75         return;
76
77 CATCH:
78         delete pPresenter;
79         pPresenter = null;
80 }
81
82 _Frame::~_Frame(void)
83 {
84         if (__pFrameEvent)
85         {
86                 delete __pFrameEvent;
87                 __pFrameEvent = null;
88         }
89
90         delete __pFramePresenter;
91         __pFramePresenter = null;
92
93         ClearLastResult();
94 }
95
96 _Frame*
97 _Frame::CreateFrameN(void)
98 {
99         //_VisualElement* pFrameVE = null;
100
101 #if defined(MULTI_WINDOW)
102         result r = E_SUCCESS;
103         _RootVisualElement* pRootVE = null;
104         _EflLayer* pLayer = null;
105 #endif
106
107         _Frame* pFrame = new (std::nothrow) _Frame;
108         SysTryCatch(NID_UI_CTRL, pFrame, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
109         SysTryCatch(NID_UI_CTRL, GetLastResult() == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] A system error occurred.");
110
111 #if defined(MULTI_WINDOW)
112         r = pFrame->CreateRootVisualElement();
113         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
114
115         pRootVE = pFrame->GetRootVisualElement();
116         SysAssert(pRootVE);
117
118         pLayer = static_cast<_EflLayer*>(pRootVE->GetNativeLayer());
119         SysAssert(pLayer);
120
121         pLayer->SetOpacity(1);
122 #endif
123
124         //pFrameVE = pFrame->GetVisualElement();
125         //pFrameVE->SetRenderOperation(_VisualElement::RENDER_OPERATION_COPY);
126
127         pFrame->AcquireHandle();
128
129         SetLastResult(E_SUCCESS);
130
131         return pFrame;
132
133 CATCH:
134         delete pFrame;
135
136         return null;
137 }
138
139 result
140 _Frame::SetPresenter(const _FramePresenter& framePresenter)
141 {
142         __pFramePresenter = const_cast <_FramePresenter*>(&framePresenter);
143
144         return E_SUCCESS;
145 }
146
147 void
148 _Frame::OnDraw(void)
149 {
150         if (__pFramePresenter)
151         {
152                 __pFramePresenter->Draw();
153         }
154 }
155
156 void
157 _Frame::OnActivated(void)
158 {
159         SysLog(NID_UI, "activated(%d)", __activated);
160
161         if (!__activated)
162         {
163                 return;
164         }
165
166 #if defined(MULTI_WINDOW)
167         _Window::OnActivated();
168 #endif
169
170         _Form* pCurrentForm = GetCurrentForm();
171         if (pCurrentForm == null)
172         {
173                 return;
174         }
175
176         _Control* pFocusedControl = pCurrentForm->GetFocused();
177         if (pFocusedControl)
178         {
179                 pFocusedControl->SetFocused();
180         }
181         else
182         {
183                 pCurrentForm->SetFocused();
184         }
185 }
186
187 bool
188 _Frame::OnNotifiedN(const _Control& source, IList* pArgs)
189 {
190         SysTryReturn(NID_UI_CTRL, pArgs, false, E_SYSTEM, "[E_SYSTEM] pArgs is null.")
191
192         String* pType = dynamic_cast <String*>(pArgs->GetAt(0));
193         SysTryReturn(NID_UI_CTRL, pType, false, E_SYSTEM, "[E_SYSTEM] pType is null.")
194
195         if (*pType == L"VisibilityEvent")
196         {
197                 int obscured = 0;
198
199                 Integer* pObscured = dynamic_cast<Integer*>(pArgs->GetAt(1));
200                 if (pObscured == null)
201                 {
202                         pArgs->RemoveAll(true);
203                         delete pArgs;
204
205                         return true;
206                 }
207
208                 obscured = pObscured->ToInt();
209                 if (obscured == 0)
210                 {
211                         __activated = true;
212                         OnFrameActivated();
213                 }
214                 else
215                 {
216                         __activated = false;
217                         OnFrameDeactivated();
218                 }
219
220                 pArgs->RemoveAll(true);
221                 delete pArgs;
222
223                 return true;
224         }
225
226         return false;
227 }
228
229 void
230 _Frame::OnFrameActivated(void)
231 {
232         int childcount = GetChildCount();
233
234         for (int i = 0 ; i < childcount ; i++)
235         {
236                 _Control* pChild = GetChild(i);
237                 _Form* pForm = dynamic_cast<_Form*>(pChild);
238                 if (pForm)
239                 {
240                         pForm->MoveOverlayRegion(true);
241                 }
242         }
243
244         // Fire Event.
245         IEventArg* pArg = _FrameEvent::CreateFrameEventArgN(*this, _FRAME_STATUS_ACTIVATED);
246         __pFrameEvent->Fire(*pArg);
247
248         if (GetChildCount() < 1)
249         {
250                 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
251                 SysTryReturnVoidResult(NID_UI_CTRL, pEcoreEvas, E_SYSTEM, "[E_SYSTEM] Unable to get evas");
252 #if !defined(MULTI_WINDOW)
253                 pEcoreEvas->SetIndicatorShowState(false);
254 #else
255                 if (GetShowMode() == FRAME_SHOW_MODE_FULL_SCREEN)
256                 {
257                         pEcoreEvas->SetIndicatorShowState(*GetRootWindow(), false);
258                 }
259 #endif
260         }
261 }
262
263 void
264 _Frame::OnFrameDeactivated(void)
265 {
266         int childcount = GetChildCount();
267
268         for (int i = 0 ; i < childcount ; i++)
269         {
270                 _Control* pChild = GetChild(i);
271                 _Form* pForm = dynamic_cast<_Form*>(pChild);
272                 if (pForm)
273                 {
274                         pForm->MoveOverlayRegion(false);
275                 }
276         }
277
278         // Fire Event.
279         IEventArg* pArg = _FrameEvent::CreateFrameEventArgN(*this, _FRAME_STATUS_DEACTIVATED);
280         __pFrameEvent->Fire(*pArg);
281
282         _TouchManager* pTouchManager = _TouchManager::GetInstance();
283         if (pTouchManager)
284         {
285                 pTouchManager->SetTouchCanceled(true);
286         }
287 }
288
289 bool
290 _Frame::IsFocusableDescendant(const _Control* pFocus) const
291 {
292         const _Control* pTopChild = GetChild(GetChildCount() - 1); // Find the current Form.
293         const _Control* pTop = pFocus;
294
295         if (pTop == this)
296         {
297                 return true;
298         }
299
300         // 1. Find the Form of the pFocus.
301         // 2. If the Form is the current Form, then return true.
302         while (pTop)
303         {
304                 if (pTop == pTopChild)
305                 {
306                         return true;
307                 }
308                 pTop = pTop->GetParent();
309         }
310
311         return false;
312 }
313
314 void
315 _Frame::SetFocusOff(_Control* pFocus)
316 {
317         _Control* pTopOfFocus = null;
318         _Control* pTemp = pFocus;
319
320         while (pTemp != this)
321         {
322                 pTopOfFocus = pTemp;
323                 pTemp = pTemp->GetParent();
324         }
325
326         // [ToDo] If pTem == null???
327
328         if (pTopOfFocus)
329         {
330                 pTopOfFocus->SetFocusOff(pFocus);
331         }
332 }
333
334 void
335 _Frame::SetCurrentForm(const _Form* pForm)
336 {
337         result r = E_SUCCESS;
338
339         SysTryReturnVoidResult(NID_UI_CTRL, pForm != null, E_INVALID_ARG, "[E_INVALID_ARG] Form to become a new current form is null");
340         _Form* pNewForm = const_cast<_Form*>(pForm);
341
342         _Form* pCurrentForm = GetCurrentForm();
343         pNewForm->AddIndicatorObject();
344
345         if (pCurrentForm != null)
346         {
347                 if (pCurrentForm != pForm)
348                 {
349                         // Change order
350                         r = MoveChildToTop(*pForm);
351                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
352                         pNewForm->MoveOverlayRegion(true);
353
354                         pCurrentForm->SetVisibleState(false);
355                         pCurrentForm->MoveOverlayRegion(false);
356
357                         if (__pFormActivationChangeEventListener)
358                                 __pFormActivationChangeEventListener->OnFormDeactivated(*pCurrentForm);
359                 }
360         }
361
362         _Control* pFocus = pNewForm->GetFocused();
363         if (pFocus)
364         {
365                 pFocus->SetFocused();
366         }
367         else
368         {
369                 pNewForm->SetFocused();
370         }
371
372         pNewForm->SetVisibleState(true);
373         pNewForm->SetUpdateLayoutState(true);
374
375         if (__pFormActivationChangeEventListener)
376                 __pFormActivationChangeEventListener->OnFormActivated(*pNewForm);
377
378         SetLastResult(E_SUCCESS);
379
380         return;
381 }
382
383 _Form*
384 _Frame::GetCurrentForm(void) const
385 {
386         _Form* pCurrentForm = null;
387         int controlCount = GetChildCount();
388
389         if (controlCount > 0)
390         {
391                 for (int i = controlCount; i > 0; i--)
392                 {
393                         pCurrentForm = dynamic_cast<_Form*>(GetChild(i - 1));
394                         SysTryReturn(NID_UI_CTRL, pCurrentForm != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
395                         if (pCurrentForm->IsVisible())
396                         {
397                                 break;
398                         }
399                 }
400         }
401
402         return pCurrentForm;
403 }
404
405 #if !defined(MULTI_WINDOW)
406 bool
407 _Frame::IsLayoutChangable(void) const
408 {
409         return false;
410 }
411 #endif
412
413 bool
414 _Frame::IsOrientationRoot(void) const
415 {
416         return true;
417 }
418
419 void
420 _Frame::AddFrameEventListener(const _IFrameEventListener& listener)
421 {
422         result r = __pFrameEvent->AddListener(listener);
423         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
424 }
425
426 void
427 _Frame::RemoveFrameEventListener(const _IFrameEventListener& listener)
428 {
429         result r = __pFrameEvent->RemoveListener(listener);
430         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
431 }
432
433 void
434 _Frame::SetFormActivationChangeEventListener(const _IFormActivationChangeEventListener* plistener)
435 {
436         __pFormActivationChangeEventListener = const_cast<_IFormActivationChangeEventListener*>(plistener);
437 }
438
439
440 void
441 _Frame::SetFloatingBounds(const Rectangle& rect)
442 {
443         __floatingBounds = rect;
444 }
445
446 result
447 _Frame::SetShowMode(FrameShowMode showMode)
448 {
449         bool changeMode = true;
450
451         if ((showMode == FRAME_SHOW_MODE_PARTIAL_SCREEN) || (showMode == FRAME_SHOW_MODE_PARTIAL_SCREEN_FLOATING))
452         {
453                 _Form* pCurrentForm = GetCurrentForm();
454
455                 if (pCurrentForm)
456                 {
457                         if (pCurrentForm->GetFormStyle() & _FORM_STYLE_INDICATOR)
458                         {
459                                 changeMode = false;
460                         }
461                 }
462         }
463
464         SysTryReturnResult(NID_UI_CTRL, changeMode == true, E_SYSTEM, "The method cannot proceed due to a severe system error.");
465
466         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
467         SysTryReturnResult(NID_UI_CTRL, pEcoreEvas, E_SYSTEM, "The method cannot proceed due to a severe system error.");
468
469         int oldShowMode = __showMode;
470         __showMode = showMode;
471
472         result r = E_SUCCESS;
473
474         switch (__showMode)
475         {
476         case FRAME_SHOW_MODE_FULL_SCREEN:
477                 if (oldShowMode == FRAME_SHOW_MODE_PARTIAL_SCREEN_FLOATING)
478                 {
479 #if !defined(MULTI_WINDOW)
480                         r = pEcoreEvas->SetFloatingMode(false);
481 #else
482                         r = pEcoreEvas->SetFloatingMode(*GetRootWindow(), false);
483 #endif
484                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
485                 }
486
487                 if (oldShowMode != FRAME_SHOW_MODE_FULL_SCREEN)
488                 {
489                         Dimension screen = _ControlManager::GetInstance()->GetScreenSize();
490
491                         __restore = true;
492
493                         if (GetOrientation() == _CONTROL_ORIENTATION_PORTRAIT)
494                         {
495                                 SetBounds(Rectangle(0, 0, screen.width, screen.height));
496                         }
497                         else
498                         {
499                                 SetBounds(Rectangle(0, 0, screen.height, screen.width));
500                         }
501
502                         __restore = false;
503                 }
504
505                 break;
506         case FRAME_SHOW_MODE_PARTIAL_SCREEN:
507                 if (oldShowMode == FRAME_SHOW_MODE_PARTIAL_SCREEN_FLOATING)
508                 {
509 #if !defined(MULTI_WINDOW)
510                         r = pEcoreEvas->SetFloatingMode(false);
511 #else
512                         r = pEcoreEvas->SetFloatingMode(*GetRootWindow(), false);
513 #endif
514                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
515                 }
516
517                 if (oldShowMode == FRAME_SHOW_MODE_FULL_SCREEN)
518                 {
519                         SetBounds(__floatingBounds);
520                 }
521                 else if (oldShowMode == FRAME_SHOW_MODE_PARTIAL_SCREEN_FLOATING)
522                 {
523 #if !defined(MULTI_WINDOW)
524                         pEcoreEvas->SetWindowBounds(__floatingBounds);
525 #else
526                         pEcoreEvas->SetWindowBounds(*GetRootWindow(), __floatingBounds);
527 #endif
528                 }
529
530                 break;
531         case FRAME_SHOW_MODE_PARTIAL_SCREEN_FLOATING:
532                 if (oldShowMode != FRAME_SHOW_MODE_PARTIAL_SCREEN_FLOATING)
533                 {
534 #if !defined(MULTI_WINDOW)
535                         r = pEcoreEvas->SetFloatingMode(true);
536 #else
537                         r = pEcoreEvas->SetFloatingMode(*GetRootWindow(), true);
538 #endif
539                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
540                 }
541
542                 if (oldShowMode == FRAME_SHOW_MODE_FULL_SCREEN)
543                 {
544                         SetBounds(__floatingBounds);
545                 }
546
547                 break;
548         default:
549                 break;
550         }
551
552         return E_SUCCESS;
553 }
554
555 FrameShowMode
556 _Frame::GetShowMode(void) const
557 {
558         return __showMode;
559 }
560
561 bool
562 _Frame::IsActivated(void) const
563 {
564         return __activated;
565 }
566
567 void
568 _Frame::OnChildAttached(const _Control& child)
569 {
570         _Form* pCurrentForm = GetCurrentForm();
571
572         if (pCurrentForm == &child)
573         {
574                 int controlCount = GetChildCount();
575
576                 if (controlCount > 1)
577                 {
578                         _Control* pOldCurrentForm = GetChild(controlCount - 2);
579                         SysTryReturnVoidResult(NID_UI_CTRL, pOldCurrentForm != null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
580                         pOldCurrentForm->SetVisibleState(false);
581                 }
582         }
583 }
584
585 void
586 _Frame::OnChildDetached(const _Control& child)
587 {
588         int controlCount = GetChildCount();
589
590         if (controlCount > 0)
591         {
592                 _Control* pCurrentForm = GetChild(controlCount - 1);
593                 SysTryReturnVoidResult(NID_UI_CTRL, pCurrentForm, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
594                 pCurrentForm->SetVisibleState(true);
595         }
596         else
597         {
598                 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
599                 SysTryReturnVoidResult(NID_UI_CTRL, pEcoreEvas, E_SYSTEM, "[E_SYSTEM] Unable to get evas");
600 #if !defined(MULTI_WINDOW)
601                 pEcoreEvas->SetIndicatorShowState(false);
602 #else
603                 pEcoreEvas->SetIndicatorShowState(*GetRootWindow(), false);
604 #endif
605         }
606 }
607
608 result
609 _Frame::OnBoundsChanging(const Rectangle& bounds)
610 {
611         if (__restore == false)
612         {
613                 __floatingBounds = bounds;
614         }
615
616         if ((__showMode == FRAME_SHOW_MODE_FULL_SCREEN) && (__restore == false))
617         {
618                 return E_SUCCESS;
619         }
620
621         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
622         SysTryReturn(NID_UI, pEcoreEvas, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
623
624 #if !defined(MULTI_WINDOW)
625         pEcoreEvas->SetWindowBounds(bounds);
626 #else
627         pEcoreEvas->SetWindowBounds(*GetRootWindow(), bounds);
628 #endif
629         result r = GetLastResult();
630         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
631
632         return r;
633 }
634
635
636 result
637 _Frame::OnAttached(void)
638 {
639         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
640         SysAssert(pEcoreEvas);
641
642 #if !defined(MULTI_WINDOW)
643         pEcoreEvas->SetWindowVisibleState(true);
644 #else
645         pEcoreEvas->SetWindowVisibleState(*GetRootWindow(), true);
646 #endif
647
648         return E_SUCCESS;
649 }
650
651 #if !defined(MULTI_WINDOW)
652 result
653 _Frame::OnAttachedToMainTree(void)
654 {
655         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
656         SysAssert(pEcoreEvas);
657
658         _RootVisualElement* pRootVE = pEcoreEvas->GetRootVisualElement();
659         SysAssert(pRootVE);
660
661         _EflLayer* pLayer = static_cast<_EflLayer*>(pRootVE->GetNativeLayer());
662         SysAssert(pLayer);
663
664         pLayer->SetShowState(true);
665         pRootVE->SetShowState(true);
666
667         return E_SUCCESS;
668 }
669
670 void
671 _Frame::OnVisibleStateChanged(void)
672 {
673         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
674         SysTryReturnVoidResult(NID_UI, pEcoreEvas, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
675
676         bool visibleState = GetVisibleState();
677
678         pEcoreEvas->SetWindowVisibleState(visibleState);
679         result r = GetLastResult();
680         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
681
682         SetLastResult(E_SUCCESS);
683 }
684 #endif
685
686 }}} // Tizen::Ui::Controls