Revert "Adjust the position of the partial Frame"
[platform/framework/native/uifw.git] / src / ui / FUi_OrientationAgent.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 /**
19  * @file        FUi_OrientationAgent.cpp
20  * @brief       This is the implementation file for the _OrientationAgent class.
21  */
22
23 #include <unique_ptr.h>
24 #include <app.h>
25 #include <FBaseSysLog.h>
26 #include <FBaseColArrayList.h>
27 #include "FUi_OrientationAgent.h"
28 #include "FUi_ControlManager.h"
29 #include "FUi_ControlImplManager.h"
30 #include "FUi_PublicOrientationEvent.h"
31 #include "FUi_ControlImpl.h"
32 #include "FUi_Window.h"
33 #include "FUiCtrl_FormImpl.h"
34 #include "FUiCtrl_FrameImpl.h"
35 #include "FUiCtrl_Frame.h"
36 #include "FUiCtrl_Form.h"
37 #include "FUi_EcoreEvasMgr.h"
38 #include "FUi_EcoreEvas.h"
39 #include "FUi_ControlManager.h"
40 #include "FUi_UiNotificationEvent.h"
41 #include "FUi_UiEventManager.h"
42
43 using namespace std;
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Base::Runtime;
47 using namespace Tizen::Ui::Controls;
48 using namespace Tizen::Graphics;
49
50 namespace Tizen { namespace Ui {
51
52 const String _REQUEST_ORIENTATION_EVENT = L"RequestOrientationEvent";
53
54 _OrientationAgent*
55 _OrientationAgent::CreateInstanceN(Control& publicControl)
56 {
57         _OrientationAgent* pAgent = new (std::nothrow) _OrientationAgent(publicControl);
58         SysTryReturn(NID_UI, pAgent, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
59
60         result r = GetLastResult();
61         SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
62
63         SetLastResult(E_SUCCESS);
64
65         return pAgent;
66
67 CATCH:
68         delete pAgent;
69         return null;
70 }
71
72 _OrientationAgent::_OrientationAgent(Control& publicControl)
73         : __publicControl(publicControl)
74         , __pPublicEvent(null)
75         , __mode(ORIENTATION_PORTRAIT)
76         , __status(ORIENTATION_STATUS_PORTRAIT)
77         , __tempStatus(ORIENTATION_STATUS_PORTRAIT)
78         , __firePublicEvent(false)
79         , __statusChanged(false)
80         , __updateStatus(true)
81 #if defined(WINDOW_BASE_ROTATE)
82         , __draw(false)
83 #endif
84 {
85         _PublicOrientationEvent* pPublicEvent = _PublicOrientationEvent::CreateInstanceN(publicControl);
86
87         result r = GetLastResult();
88         SysTryReturnVoidResult(NID_UI, pPublicEvent, r, "[%s] Propagating.", GetErrorMessage(r));
89
90         __pPublicEvent = pPublicEvent;
91
92         SetLastResult(E_SUCCESS);
93 }
94
95 _OrientationAgent::~_OrientationAgent(void)
96 {
97         if (__pPublicEvent)
98         {
99                 delete __pPublicEvent;
100                 __pPublicEvent = null;
101         }
102 }
103
104 void
105 _OrientationAgent::AddListener(IOrientationEventListener& listener)
106 {
107         result r = __pPublicEvent->AddListener(listener);
108         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
109
110         SetLastResult(E_SUCCESS);
111 }
112
113 void
114 _OrientationAgent::RemoveListener(IOrientationEventListener& listener)
115 {
116         result r = __pPublicEvent->RemoveListener(listener);
117         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
118
119         SetLastResult(E_SUCCESS);
120 }
121
122 Orientation
123 _OrientationAgent::GetMode(void) const
124 {
125         return __mode;
126 }
127
128 OrientationStatus
129 _OrientationAgent::GetStatus(void) const
130 {
131         return __status;
132 }
133
134 void
135 _OrientationAgent::SetMode(Orientation mode)
136 {
137         SysTryReturnVoidResult(NID_UI, mode != ORIENTATION_NONE, E_INVALID_ARG, "[E_INVALID_ARG] A specified input parameter is invalid.");
138
139         SetLastResult(E_SUCCESS);
140
141         if (__mode == mode)
142         {
143                 return;
144         }
145
146         __mode = mode;
147         Update();
148 }
149
150 void
151 _OrientationAgent::Update(bool draw)
152 {
153 #if defined(WINDOW_BASE_ROTATE)
154         // Update orientation status(Not Auto-mode)
155         // Request rotation to window manager -> async -> Update VEs
156         // Window(not rotation) -> sync -> UpdateVEs
157
158         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
159         SysAssert(pImplManager);
160
161         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
162         if (!pImpl)
163         {
164                 return;
165         }
166
167         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
168         if (!pEcoreEvas)
169         {
170                 return;
171         }
172
173         bool autoMode = false;
174
175         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
176         {
177                 autoMode = true;
178         }
179
180 //      if (autoMode == false)
181 //      {
182                 // [Sync]
183                 // Update orientation status
184                 // Update VEs
185                 // Fire orientation event
186                 // Rotate screen
187                 // Set preffered rotation
188
189                 OrientationStatus status = pImplManager->GetOrientationStatus(__mode);
190                 SysLog(NID_UI, "[Window Manager Rotation] Update : __mode(%d) -> status(%d)", __mode, status);
191                 
192                 if (__updateStatus == true)
193                 {
194                         __statusChanged = false;
195                         if (__status != status)
196                         {
197                                 __statusChanged = true;
198                                 __updateStatus = false;
199                         }
200                 }
201                 
202                 __status = status;
203                 
204                 pEcoreEvas->AllowSetWindowBounds(false);
205                 FireEvent(status);
206                 pEcoreEvas->AllowSetWindowBounds(true);
207                 
208                 // For the form to be made by Ui-Builder
209                 if ((draw == true) && (__statusChanged == true))
210                 {
211                         _ControlOrientation coreOrientation =
212                                 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
213                                 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
214                 
215                         Rectangle temp;
216                         bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
217                         if (exist)
218                         {
219                                 pImpl->Invalidate(true);
220                         }
221                 }
222                 
223                 // Despite not changing status, it needs to rotate screen.
224                 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(__publicControl);
225                 pImplManager->RotateScreen(pControlImpl, status);
226
227                 _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
228                 if (pRootWindow)
229                 {
230                         SetRotation(*pRootWindow, __mode);
231                 }
232 //      }
233 //      else
234 //      {
235                 // [Async]
236                 // Set preffered rotation
237
238 //              _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
239 //              if (pRootWindow)
240 //              {
241 //                      SetRotation(*pRootWindow, __mode);
242 //              }
243
244                 __draw = draw;
245 //      }
246 #else           
247         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
248         SysAssert(pImplManager);
249
250         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
251         if (!pImpl)
252         {
253                 return;
254         }
255
256         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
257         if (!pEcoreEvas)
258         {
259                 return;
260         }
261
262         _Form* pForm = dynamic_cast<_Form*>(&(pImpl->GetCore()));
263         if (pForm)
264         {
265                 _Control* pParent = pForm->GetParent();
266
267                 if (pParent)
268                 {
269                         int index = pParent->GetChildIndex(*pForm);
270                         int childCount = pParent->GetChildCount();
271
272                         if (index == (childCount - 1))
273                         {
274                                 _Window* pWindow = pForm->GetRootWindow();
275                                 if (pWindow)
276                                 {
277                                         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
278                                         {
279                                                 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, true);
280                                                 pWindow->SetOrientationEnabled(true);
281                                         }
282                                         else
283                                         {
284                                                 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, false);
285                                                 pWindow->SetOrientationEnabled(false);
286                                         }
287                                 }
288                         }
289                 }
290         }
291         else
292         {
293                 _Frame* pFrame = dynamic_cast<_Frame*>(&(pImpl->GetCore()));
294                 if (pFrame)
295                 {
296                         int childCount = pFrame->GetChildCount();
297                         if (childCount == 0)
298                         {
299                                 _Window* pCurrentFrame = _ControlManager::GetInstance()->GetCurrentFrame();
300                                 if (pCurrentFrame == pFrame)
301                                 {
302                                         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
303                                         {
304                                                 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, true);
305                                                 pFrame->SetOrientationEnabled(true);
306                                         }
307                                         else
308                                         {
309                                                 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, false);
310                                                 pFrame->SetOrientationEnabled(false);
311                                         }
312                                 }
313                         }
314                 }
315         }
316
317         OrientationStatus status = pImplManager->GetOrientationStatus(__mode);
318
319         if (__updateStatus == true)
320         {
321                 __statusChanged = false;
322                 if (__status != status)
323                 {
324                         __statusChanged = true;
325                         __updateStatus = false;
326                 }
327         }
328
329         __status = status;
330
331         pEcoreEvas->AllowSetWindowBounds(false);
332         FireEvent(status);
333         pEcoreEvas->AllowSetWindowBounds(true);
334
335         // For the form to be made by Ui-Builder
336         if ((draw == true) && (__statusChanged == true))
337         {
338                 _ControlOrientation coreOrientation =
339                         (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
340                         _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
341
342                 Rectangle temp;
343                 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
344                 if (exist)
345                 {
346                         pImpl->Invalidate(true);
347                 }
348         }
349
350         // Despite not changing status, it needs to rotate screen.
351         _ControlImpl* pControlImpl = _ControlImpl::GetInstance(__publicControl);
352         pImplManager->RotateScreen(pControlImpl, status);
353 #endif
354 }
355
356 #if defined(WINDOW_BASE_ROTATE)
357 void
358 _OrientationAgent::UpdateOrientation(void)
359 {
360         // Get window rotation
361         // Update VEs
362         // Fire orientation event
363         // Update window bounds
364         // Invalidate
365
366         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
367         if (!pEcoreEvas)
368         {
369                 return;
370         }
371
372         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
373         if (!pImpl)
374         {
375                 return;
376         }
377
378         _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
379         if (!pRootWindow)
380         {
381                 return;
382         }
383
384         int rotation = pEcoreEvas->GetWindowRotation(*pRootWindow);
385         OrientationStatus status = ORIENTATION_STATUS_NONE;
386         switch (rotation)
387         {
388         case 0:
389                 status = ORIENTATION_STATUS_PORTRAIT;
390                 break;
391         case 270:
392                 status = ORIENTATION_STATUS_LANDSCAPE;
393                 break;
394         case 180:
395                 status = ORIENTATION_STATUS_PORTRAIT_REVERSE;
396                 break;
397         case 90:
398                 status = ORIENTATION_STATUS_LANDSCAPE_REVERSE;
399                 break;
400         default:
401                 break;
402         }
403
404         if (__updateStatus == true)
405         {
406                 __statusChanged = false;
407                 if (__status != status)
408                 {
409                         __statusChanged = true;
410                         __updateStatus = false;
411                 }
412         }
413
414         __status = status;
415
416         pEcoreEvas->AllowSetWindowBounds(false);
417         FireEvent(status);
418         pEcoreEvas->AllowSetWindowBounds(true);
419
420         // For the form to be made by Ui-Builder
421         if ((__draw == true) && (__statusChanged == true))
422         {
423                 _ControlOrientation coreOrientation =
424                         (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
425                         _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
426
427                 Rectangle temp;
428                 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
429                 if (exist)
430                 {
431                         pImpl->Invalidate(true);
432                 }
433         }
434
435         pEcoreEvas->RotateWindow(*pRootWindow, rotation);
436
437         pImpl->Invalidate(true);
438
439         Rectangle bounds = pRootWindow->GetBounds();
440         SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x, rot = %d, %d, %d, %d, %d] Update Orientation.", pRootWindow->GetNativeHandle(), rotation, bounds.x, bounds.y, bounds.width, bounds.height);
441 }
442 #endif
443
444 void
445 _OrientationAgent::RequestOrientationEvent(void)
446 {
447         ClearLastResult();
448
449         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
450         SysTryReturnVoidResult(NID_UI, pImpl, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
451
452         unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
453         SysTryReturnVoidResult(NID_UI, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
454         pEventArgs->Construct();
455
456         unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(_REQUEST_ORIENTATION_EVENT));
457         SysTryReturnVoidResult(NID_UI, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
458
459         pEventArgs->Add(*(pString.get()));
460         
461         _UiNotificationEvent event(pImpl->GetCore().GetHandle(), pEventArgs.get());
462
463         result r = _UiEventManager::GetInstance()->PostEvent(event);
464         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
465
466         pString.release();
467         pEventArgs.release();
468 }
469
470 void
471 _OrientationAgent::FireOrientationEvent(void)
472 {
473         if (__firePublicEvent)
474         {
475                 return;
476         }
477
478         __firePublicEvent = true;
479
480         SysLog(NID_UI, "Fire the orientation event.");
481
482         if (__statusChanged)
483         {
484                 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), __status);
485                 __pPublicEvent->Fire(*pArg);
486
487                 __updateStatus = true;
488         }
489 }
490
491 void
492 _OrientationAgent::FireEvent(OrientationStatus status)
493 {
494         ClearLastResult();
495
496         _ControlManager* pCoreManager = _ControlManager::GetInstance();
497         SysAssert(pCoreManager);
498
499         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
500         if (!pImpl)
501         {
502                 return;
503         }
504
505         _ControlOrientation coreOrientation =
506                 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
507                 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
508
509         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
510         SysAssert(pImplManager);
511
512         // Core
513         pCoreManager->SetOrientation(coreOrientation);
514         pImplManager->SetOrientationStatus(status);
515         pImpl->GetCore().ChangeLayout(coreOrientation);
516
517 #if !defined(WINDOW_BASE_ROTATE)
518         // Ownee
519         int owneeCount = pImpl->GetCore().GetOwneeCount();
520         for (int i = 0; i < owneeCount; i++)
521         {
522                 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
523
524                 if (pOwnee)
525                 {
526                         pOwnee->ChangeLayout(coreOrientation);
527                 }
528         }
529 #endif
530
531         // Public
532         if (__firePublicEvent && __statusChanged)
533         {
534                 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), status);
535                 __pPublicEvent->Fire(*pArg);
536
537                 __updateStatus = true;
538         }
539 }
540
541 #if defined(WINDOW_BASE_ROTATE)
542 void
543 _OrientationAgent::SetRotation(const _Window& window, Orientation orientation)
544 {
545         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
546         if (!pEcoreEvas)
547         {
548                 return;
549         }
550
551         switch (orientation)
552         {
553         case ORIENTATION_PORTRAIT:
554                 pEcoreEvas->SetWindowPreferredRotation(window, 0);
555                 break;
556         case ORIENTATION_LANDSCAPE:
557                 pEcoreEvas->SetWindowPreferredRotation(window, 270);
558                 break;
559         case ORIENTATION_PORTRAIT_REVERSE:
560                 pEcoreEvas->SetWindowPreferredRotation(window, 180);
561                 break;
562         case ORIENTATION_LANDSCAPE_REVERSE:
563                 pEcoreEvas->SetWindowPreferredRotation(window, 90);
564                 break;
565         case ORIENTATION_AUTOMATIC:
566                 {
567                         pEcoreEvas->SetWindowPreferredRotation(window, -1);
568                         int autoRotation[3] = {0, 90, 270};
569                         pEcoreEvas->SetWindowAvailabledRotation(window, autoRotation, 3);
570                 }
571
572                 break;
573         case ORIENTATION_AUTOMATIC_FOUR_DIRECTION:
574                 {
575                         pEcoreEvas->SetWindowPreferredRotation(window, -1);
576                         int autoFourRotation[4] = {0, 90, 180, 270};
577                         pEcoreEvas->SetWindowAvailabledRotation(window, autoFourRotation, 4);
578                 }
579
580                 break;
581         default:
582                 break;
583         }
584
585         // [Ownee]
586         // 1. ActivateWindow
587         // 2. SetOwner
588         // 3. SetRotation
589
590         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
591         if (!pImpl)
592         {
593                 return;
594         }
595
596         int owneeCount = pImpl->GetCore().GetOwneeCount();
597         for (int i = 0; i < owneeCount; i++)
598         {
599                 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
600                 if (pOwnee)
601                 {
602                         pEcoreEvas->SetOwner(*pOwnee, pImpl->GetCore());
603                 }
604         }
605
606         _Control* pParent = pImpl->GetCore().GetParent();
607         if (pParent)
608         {
609                 int owneeCount = pParent->GetOwneeCount();
610                 for (int i = 0; i < owneeCount; i++)
611                 {
612                         _Window* pOwnee = pParent->GetOwnee(i);
613                         if (pOwnee)
614                         {
615                                 pEcoreEvas->SetOwner(*pOwnee, *pParent);
616                         }
617                 }
618         }
619 }
620 #endif
621
622 }} // Tizen::Ui