Fix Ime Rotation
[platform/framework/native/uifw.git] / src / ui / controls / FUiCtrl_FrameImpl.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 <new>
19 #include <FUiCtrlForm.h>
20 #include <FUiAnimFrameAnimator.h>
21 #include <FUiCtrlIFrameEventListener.h>
22 #include <FBaseSysLog.h>
23 #include <FApp_AppInfo.h>
24 #include "FUi_ControlManager.h"
25 #include "FUi_OrientationAgent.h"
26 #include "FUi_ImeOrientationAgent.h"
27 #include "FUi_CoordinateSystemUtils.h"
28 #include "FUiCtrlForm.h"
29 #include "FUiCtrl_FrameImpl.h"
30 #include "FUiCtrl_FormImpl.h"
31 #include "FUiCtrl_Frame.h"
32 #include "FUiCtrl_PublicFrameEvent.h"
33
34 using namespace Tizen::App;
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 using namespace Tizen::Ui::Animations;
41
42 namespace Tizen { namespace Ui { namespace Controls {
43
44 const String _REQUEST_ORIENTATION_EVENT = L"RequestOrientationEvent";
45
46 const _FrameImpl*
47 _FrameImpl::GetInstance(const Frame& frame)
48 {
49         return static_cast<const _FrameImpl*> (frame._pControlImpl);
50 }
51
52 _FrameImpl*
53 _FrameImpl::GetInstance(Frame& frame)
54 {
55         return static_cast<_FrameImpl*> (frame._pControlImpl);
56 }
57
58 void
59 _FrameImpl::Dispose(void)
60 {
61         GetCore().RemoveFrameEventListener(*this);
62
63         if (__pFrameEvent)
64         {
65                 delete __pFrameEvent;
66                 __pFrameEvent = null;
67         }
68
69         if (__pOrientationAgent)
70         {
71                 delete __pOrientationAgent;
72                 __pOrientationAgent = null;
73         }
74
75         if (__pImeOrientationAgent)
76         {
77                 delete __pImeOrientationAgent;
78                 __pImeOrientationAgent = null;
79         }
80
81         delete __pFrameAnimator;
82         __pFrameAnimator = null;
83 }
84
85 _FrameImpl::_FrameImpl(Frame* pPublic, _Frame* pCore)
86         : _WindowImpl(pPublic, pCore)
87         , __pFrameEvent(null)
88         , __pFrameAnimator(null)
89         , __pOrientationAgent(null)
90         , __pImeOrientationAgent(null)
91 {
92         __pFrameEvent = _PublicFrameEvent::CreateInstanceN(*pPublic);
93         SysTryReturnVoidResult(NID_UI_CTRL, __pFrameEvent, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
94
95         int appType = _AppInfo::GetAppType();
96         if (appType & _APP_TYPE_IME_APP)
97         {
98                 __pImeOrientationAgent = _ImeOrientationAgent::CreateInstanceN(*pPublic);
99                 SysTryCatch(NID_UI_CTRL, __pImeOrientationAgent != null, , GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
100         }
101         else
102         {
103                 __pOrientationAgent = _OrientationAgent::CreateInstanceN(*pPublic);
104                 SysTryCatch(NID_UI_CTRL, __pOrientationAgent != null, , GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
105         }
106
107         return;
108
109 CATCH:
110         Dispose();
111 }
112
113 _FrameImpl::~_FrameImpl(void)
114 {
115         // [ToDo] Wrong point to call OnFrameTerminating().
116         if (__pFrameEvent)
117         {
118                 IEventArg* pEventArg = _PublicFrameEvent::CreateFrameEventArgN(_FrameImpl::GetPublic(), FRAME_STATE_TERMINATING);
119                 if (pEventArg)
120                 {
121                         __pFrameEvent->Fire(*pEventArg);
122                 }
123         }
124
125         Dispose();
126         ClearLastResult();
127 }
128
129 const char*
130 _FrameImpl::GetPublicClassName(void) const
131 {
132         return "Tizen::Ui::Controls::Frame";
133 }
134
135 const Frame&
136 _FrameImpl::GetPublic(void) const
137 {
138         return static_cast<const Frame&>(_ControlImpl::GetPublic());
139 }
140
141 Frame&
142 _FrameImpl::GetPublic(void)
143 {
144         return static_cast<Frame&>(_ControlImpl::GetPublic());
145 }
146
147 const _Frame&
148 _FrameImpl::GetCore(void) const
149 {
150         return static_cast<const _Frame&>(_ControlImpl::GetCore());
151 }
152
153 _Frame&
154 _FrameImpl::GetCore(void)
155 {
156         return static_cast<_Frame&>(_ControlImpl::GetCore());
157 }
158
159 result
160 _FrameImpl::SetCurrentForm(const _FormImpl& formImpl)
161 {
162         result r = E_SUCCESS;
163
164         _FormImpl* pNewCurForm = const_cast<_FormImpl*>(&formImpl);
165
166         SysTryReturn(NID_UI_CTRL,
167                 pNewCurForm != null, E_INVALID_ARG,
168                 E_INVALID_ARG, "[E_INVALID_ARG] The Form is not initialized.");
169
170         SysTryReturn(NID_UI_CTRL,
171                 IsAncestorOf(pNewCurForm), E_INVALID_ARG,
172                 E_INVALID_ARG, "[E_INVALID_ARG] The Form is not the child of this Frame.");
173
174         if (GetCore().GetShowMode() != FRAME_SHOW_MODE_FULL_SCREEN)
175         {
176                 SysTryReturn(NID_UI_CTRL, !(pNewCurForm->GetFormStyle() & FORM_STYLE_INDICATOR), E_INVALID_ARG, E_INVALID_ARG, "Only Frame whose show mode is @c FRAME_SHOW_MODE_FULL_SCREEN can set a Form which has the style of @c FORM_STYLE_INDICATOR as the current form.");
177         }
178
179
180         r = MoveChildToTop(*pNewCurForm);
181         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
182
183         // [ToDo] Change the method to return result. And the arg should be reference.
184         GetCore().SetCurrentForm(&pNewCurForm->GetCore());
185         r = GetLastResult();
186         SysAssert(r == E_SUCCESS); // [ToDo] Exception check.
187
188         pNewCurForm->UpdateOrientationStatus();
189
190         // [ToDo] Check last result
191         SysAssert(GetLastResult() == E_SUCCESS);
192         return E_SUCCESS;
193 }
194
195 result
196 _FrameImpl::SetCurrentForm(_FormImpl* pFormImpl)
197 {
198         result r = E_SUCCESS;
199
200         _FormImpl* pNewCurForm = pFormImpl;
201
202         SysTryReturn(NID_UI_CTRL,
203                 pNewCurForm != null, E_INVALID_ARG,
204                 E_INVALID_ARG, "[E_INVALID_ARG] The Form is not initialized.");
205
206         SysTryReturn(NID_UI_CTRL,
207                 IsAncestorOf(pNewCurForm), E_INVALID_ARG,
208                 E_INVALID_ARG, "[E_INVALID_ARG] The Form is not the child of this Frame.");
209
210         if (GetCore().GetShowMode() != FRAME_SHOW_MODE_FULL_SCREEN)
211         {
212                 SysTryReturn(NID_UI_CTRL, !(pNewCurForm->GetFormStyle() & FORM_STYLE_INDICATOR), E_INVALID_ARG, E_INVALID_ARG, "Only Frame whose show mode is @c FRAME_SHOW_MODE_FULL_SCREEN can set a Form which has the style of @c FORM_STYLE_INDICATOR as the current form.");
213         }
214
215
216         r = MoveChildToTop(*pNewCurForm);
217         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
218
219         // [ToDo] Change the method to return result. And the arg should be reference.
220         GetCore().SetCurrentForm(&pNewCurForm->GetCore());
221         r = GetLastResult();
222         SysAssert(r == E_SUCCESS); // [ToDo] Exception check.
223
224         pNewCurForm->UpdateOrientationStatus();
225
226         // [ToDo] Check last result
227         SysAssert(GetLastResult() == E_SUCCESS);
228         return E_SUCCESS;
229 }
230
231 // [ToDo] This function should return _FormImpl*.
232 _FormImpl*
233 _FrameImpl::GetCurrentForm(void) const
234 {
235         _Control* pFormCore = GetCore().GetCurrentForm();
236         SysTryReturn(NID_UI_CTRL, pFormCore, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
237
238         _FormImpl* pFormImpl = static_cast<_FormImpl*>(pFormCore->GetUserData());
239
240         return pFormImpl;
241 }
242
243 _FrameImpl*
244 _FrameImpl::CreateFrameImplN(Frame* pPublic)
245 {
246         ClearLastResult();
247         result r = E_SUCCESS;
248
249         _Frame* pCore = _Frame::CreateFrameN();
250         SysTryReturn(NID_UI_CTRL, pCore, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
251
252         _FrameImpl* pImpl = new (std::nothrow) _FrameImpl(pPublic, pCore);
253         r = _ControlImpl::CheckConstruction(pCore, pImpl);
254         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
255
256         pCore->SetSize(_ControlManager::GetInstance()->GetScreenSizeF());
257
258         pCore->AddFrameEventListener(*pImpl);
259
260         SetLastResult(E_SUCCESS);
261
262         return pImpl;
263 }
264
265 void
266 _FrameImpl::AddFrameEventListener(IFrameEventListener& listener)
267 {
268         result r = __pFrameEvent->AddListener(listener);
269         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
270 }
271
272 void
273 _FrameImpl::RemoveFrameEventListener(IFrameEventListener& listener)
274 {
275         result r = __pFrameEvent->RemoveListener(listener);
276         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
277 }
278
279 Animations::FrameAnimator*
280 _FrameImpl::GetFrameAnimator(void) const
281 {
282         if (__pFrameAnimator == null)
283         {
284                 FrameAnimator* pFrameAnimator = new (std::nothrow) FrameAnimator();
285                 SysTryReturn(NID_UI_CTRL,
286                         pFrameAnimator != null, null,
287                         E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
288
289                 result r = pFrameAnimator->Construct(GetPublic());
290                 if (IsFailed(r))
291                 {
292                         SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] FrameAnimator::Construct failed");
293                         delete pFrameAnimator;
294                         return null;
295                 }
296
297                 const_cast<_FrameImpl*>(this)->__pFrameAnimator = pFrameAnimator;
298         }
299
300         SetLastResult(E_SUCCESS);
301
302         return __pFrameAnimator;
303 }
304
305 void
306 _FrameImpl::OnDraw(void)
307 {
308         if (__pOrientationAgent)
309         {
310                 __pOrientationAgent->FireOrientationEvent();
311         }
312
313         _WindowImpl::OnDraw();
314 }
315
316 void
317 _FrameImpl::OnChangeLayout(_ControlOrientation orientation)
318 {
319         // Change layout.
320         _ContainerImpl::OnChangeLayout(orientation);
321         SysTryReturnVoidResult(NID_UI_CTRL, GetLastResult() == E_SUCCESS, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
322
323         bool resizable = IsResizable();
324         SetResizable(true);
325
326         _ControlManager* pCoreManager = _ControlManager::GetInstance();
327         SysAssert(pCoreManager);
328         const FloatDimension& screenSize = pCoreManager->GetScreenSizeF();
329
330         FrameShowMode frameShowMode = GetCore().GetShowMode();
331
332         if (frameShowMode == FRAME_SHOW_MODE_FULL_SCREEN)
333         {
334                 GetCore().SetRotation(true);
335         
336                 if (orientation == _CONTROL_ORIENTATION_PORTRAIT)
337                 {
338                         SetSize(screenSize);
339                 }
340                 else
341                 {
342                         SetSize(FloatDimension(screenSize.height, screenSize.width));
343                 }
344
345                 GetCore().SetRotation(false);
346         }
347         else if ((frameShowMode == FRAME_SHOW_MODE_PARTIAL_SCREEN) || (frameShowMode == FRAME_SHOW_MODE_PARTIAL_SCREEN_FLOATING))
348         {
349                 // Adjust the position of the partial Frame.
350                 bool movable = IsMovable();
351                 SetMovable(true);
352
353                 FloatPoint prevPoint = GetPositionF();
354                 FloatPoint curPoint(0.0f, 0.0f);
355
356                 if (orientation == _CONTROL_ORIENTATION_PORTRAIT)
357                 {
358                         curPoint.x = screenSize.width / screenSize.height * prevPoint.x;
359                         curPoint.y = screenSize.height / screenSize.width * prevPoint.y;
360                 }
361                 else
362                 {
363                         curPoint.x = screenSize.height / screenSize.width * prevPoint.x;
364                         curPoint.y = screenSize.width / screenSize.height * prevPoint.y;
365                 }
366
367                 SetPosition(curPoint);
368
369                 SetMovable(movable);
370         }
371
372         SetResizable(resizable);
373 }
374
375 void
376 _FrameImpl::OnChildDetaching(const _Control& child)
377 {
378         result r = E_SUCCESS;
379
380         _FormImpl* pFormImpl = static_cast<_FormImpl*>(child.GetUserData());
381
382         _FormImpl* pCurrentForm = GetCurrentForm();
383
384         if (pCurrentForm != null)
385         {
386                 if (pCurrentForm == pFormImpl)
387                 {
388                         // if the given control will be the current form, hide the current form
389                         int count = GetChildCount();
390                         if (count > 1)
391                         {
392                                 _ControlImpl* pControlImpl = GetChild(count - 2);
393                                 if (!pControlImpl)
394                                 {
395                                         return ;
396                                 }
397
398                                 Form* pPrevForm = static_cast<Form*>(&pControlImpl->GetPublic());
399
400                                 if (pPrevForm != null)
401                                 {
402                                         r = pPrevForm->SetShowState(true);
403                                         if (IsFailed(r))
404                                         {
405                                                 SysLogException(NID_UI_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
406                                                 return ;
407                                         }
408                                 }
409                         }
410                 }
411         }
412 }
413
414 void
415 _FrameImpl::OnChildDetached(const _Control& child)
416 {
417         _ControlImpl::OnChildDetached(child);
418
419         int childCount = GetCore().GetChildCount();
420         if (childCount == 0)
421         {
422                 UpdateOrientationStatus();
423         }
424         else if (childCount > 0)
425         {
426                 _Control* pControl = GetCore().GetChild(childCount - 1);
427                 _ControlImpl* pControlImpl = static_cast<_ControlImpl*>(pControl->GetUserData());
428                 _FormImpl* pCurrentFormImpl = dynamic_cast<_FormImpl*>(pControlImpl);
429                 SysTryReturnVoidResult(NID_UI_CTRL, pCurrentFormImpl, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
430                 pCurrentFormImpl->UpdateOrientationStatus(true);
431         }
432 }
433
434 void
435 _FrameImpl::OnFrameActivated(const _Frame& source)
436 {
437         if (__pFrameEvent)
438         {
439                 IEventArg* pEventArg = _PublicFrameEvent::CreateFrameEventArgN(_FrameImpl::GetPublic(), FRAME_STATE_ACTIVATED);
440                 if (pEventArg)
441                 {
442                         __pFrameEvent->Fire(*pEventArg);
443                 }
444         }
445 }
446
447 void
448 _FrameImpl::OnFrameDeactivated(const _Frame& source)
449 {
450         if (__pFrameEvent)
451         {
452                 IEventArg* pEventArg = _PublicFrameEvent::CreateFrameEventArgN(_FrameImpl::GetPublic(), FRAME_STATE_DEACTIVATED);
453                 if (pEventArg)
454                 {
455                         __pFrameEvent->Fire(*pEventArg);
456                 }
457         }
458 }
459
460 void
461 _FrameImpl::OnFrameMinimized(const _Frame& source)
462 {
463         if (__pFrameEvent)
464         {
465                 IEventArg* pEventArg = _PublicFrameEvent::CreateFrameEventArgN(_FrameImpl::GetPublic(), FRAME_STATE_MINIMIZED);
466                 if (pEventArg)
467                 {
468                         __pFrameEvent->Fire(*pEventArg);
469                 }
470         }
471 }
472
473 void
474 _FrameImpl::OnFrameRestored(const _Frame& source)
475 {
476         if (__pFrameEvent)
477         {
478                 IEventArg* pEventArg = _PublicFrameEvent::CreateFrameEventArgN(_FrameImpl::GetPublic(), FRAME_STATE_RESTORED);
479                 if (pEventArg)
480                 {
481                         __pFrameEvent->Fire(*pEventArg);
482                 }
483         }
484 }
485
486 void
487 _FrameImpl::OnBoundsChanged(void)
488 {
489         int childcount = GetChildCount();
490         FloatRectangle bounds = GetBoundsF();
491
492         for (int i = 0 ; i < childcount ; i++)
493         {
494                 _ControlImpl* pChild = GetChild(i);
495                 _FormImpl* pForm = dynamic_cast<_FormImpl*>(pChild);
496                 if (pForm)
497                 {
498                         if (GetShowMode() == FRAME_SHOW_MODE_FULL_SCREEN)
499                         {
500                                 if (pForm->GetOrientationStatus() == ORIENTATION_STATUS_PORTRAIT || pForm->GetOrientationStatus() == ORIENTATION_STATUS_PORTRAIT_REVERSE)
501                                 {
502                                         pForm->SetBounds(FloatRectangle(0.0f, 0.0f, bounds.width, bounds.height));
503                                 }
504                                 else
505                                 {
506                                         pForm->SetBounds(FloatRectangle(0.0f, 0.0f, bounds.height, bounds.width));
507                                 }
508                         }
509                         else
510                         {
511                                 pForm->SetBounds(FloatRectangle(0.0f, 0.0f, bounds.width, bounds.height));
512                         }
513
514                 }
515         }
516
517         _ContainerImpl::OnBoundsChanged();
518
519 }
520
521 result
522 _FrameImpl::OnAttachedToMainTree(void)
523 {
524         result r = _WindowImpl::OnAttachedToMainTree();
525         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
526
527         if (__pOrientationAgent)
528         {
529                 __pOrientationAgent->RequestOrientationEvent();
530         }
531
532         return r;
533 }
534
535 bool
536 _FrameImpl::OnNotifiedN(const _ControlImpl& source, IList* pArgs)
537 {
538         String* pString = dynamic_cast <Tizen::Base::String*>(pArgs->GetAt(0));
539         if (pString)
540         {
541                 if (*pString == _REQUEST_ORIENTATION_EVENT)
542                 {
543                         if (__pOrientationAgent)
544                         {
545                                 __pOrientationAgent->FireOrientationEvent();
546                         }
547
548                         pArgs->RemoveAll(true);
549                         delete pArgs;
550
551                         return true;
552                 }
553         }
554
555         return false;
556 }
557
558 void
559 _FrameImpl::AddOrientationEventListener(Tizen::Ui::IOrientationEventListener& listener)
560 {
561         if (__pOrientationAgent)
562         {
563                 __pOrientationAgent->AddListener(listener);
564         }
565         else if (__pImeOrientationAgent)
566         {
567                 __pImeOrientationAgent->AddListener(listener);
568         }
569 }
570
571 void
572 _FrameImpl::RemoveOrientationEventListener(Tizen::Ui::IOrientationEventListener& listener)
573 {
574         if (__pOrientationAgent)
575         {
576                 __pOrientationAgent->RemoveListener(listener);
577         }
578         else if (__pImeOrientationAgent)
579         {
580                 __pImeOrientationAgent->RemoveListener(listener);
581         }
582 }
583
584 void
585 _FrameImpl::SetOrientation(Orientation orientation)
586 {
587         if (__pOrientationAgent)
588         {
589                 __pOrientationAgent->SetMode(orientation);
590         }
591 }
592
593 Orientation
594 _FrameImpl::GetOrientation(void) const
595 {
596         if (__pOrientationAgent)
597         {
598                 return __pOrientationAgent->GetMode();
599         }
600
601         return ORIENTATION_NONE;
602 }
603
604 OrientationStatus
605 _FrameImpl::GetOrientationStatus(void) const
606 {
607         if (__pOrientationAgent)
608         {
609                 return __pOrientationAgent->GetStatus();
610         }
611
612         return ORIENTATION_STATUS_NONE;
613 }
614
615 bool
616 _FrameImpl::IsChildAttachable(_ControlImpl& child) const
617 {
618         return (dynamic_cast<_FormImpl*>(&child) != null);
619 }
620
621 void
622 _FrameImpl::UpdateOrientationStatus(void)
623 {
624         if (__pOrientationAgent)
625         {
626                 __pOrientationAgent->Update();
627         }
628 }
629
630 #if defined(WINDOW_BASE_ROTATE)
631 void
632 _FrameImpl::UpdateOrientation(void)
633 {
634         if (__pOrientationAgent)
635         {
636                 __pOrientationAgent->UpdateOrientation();
637         }
638 }
639 #endif
640
641 void
642 _FrameImpl::UpdateOrientation(int angle)
643 {
644         SysLog(NID_UI_CTRL, "[Ime Rotation]");
645
646         if (__pImeOrientationAgent)
647         {
648                 __pImeOrientationAgent->UpdateOrientation(angle);
649         }
650 }
651
652 bool
653 _FrameImpl::IsOpaque(void) const
654 {
655         //return true;
656         return false;
657 }
658
659 void
660 _FrameImpl::SetFloatingBounds(const FloatRectangle& rect)
661 {
662         GetCore().SetFloatingBounds(rect);
663 }
664
665 void
666 _FrameImpl::SetFloatingBounds(const Rectangle& rect)
667 {
668         GetCore().SetFloatingBounds(rect);
669 }
670
671 result
672 _FrameImpl::SetShowMode(FrameShowMode showMode)
673 {
674         return GetCore().SetShowMode(showMode);
675 }
676
677 FrameShowMode
678 _FrameImpl::GetShowMode(void) const
679 {
680         return GetCore().GetShowMode();
681 }
682
683 }}} // Tizen::Ui::Controls