modify license, permission and remove ^M char
[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         SysLog(NID_UI, "[Window Manager Rotation] ---------- Update : START ----------");
159
160         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
161         SysAssert(pImplManager);
162
163         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
164         if (!pImpl)
165         {
166                 return;
167         }
168
169         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
170         if (!pEcoreEvas)
171         {
172                 return;
173         }
174
175         bool autoMode = false;
176
177         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
178         {
179                 autoMode = true;
180         }
181
182 //      if (autoMode == false)
183 //      {
184                 // [Sync]
185                 // Update orientation status
186                 // Update VEs
187                 // Fire orientation event
188                 // Rotate screen
189                 // Set preffered rotation
190
191                 _Window* pWindow = pImpl->GetCore().GetRootWindow();
192                 NativeWindowHandle handle = 0;
193                 if (pWindow)
194                 {
195                         handle = pWindow->GetNativeHandle();
196                 }
197
198                 OrientationStatus status = pImplManager->GetOrientationStatus(__mode);
199                 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x] Update : __mode(%d) -> status(%d)", handle, __mode, status);
200                 
201                 if (__updateStatus == true)
202                 {
203                         __statusChanged = false;
204                         if (__status != status)
205                         {
206                                 __statusChanged = true;
207                                 __updateStatus = false;
208                         }
209                 }
210                 
211                 __status = status;
212                 
213                 pEcoreEvas->AllowSetWindowBounds(false);
214                 FireEvent(status);
215                 pEcoreEvas->AllowSetWindowBounds(true);
216                 
217                 // For the form to be made by Ui-Builder
218                 if ((draw == true) && (__statusChanged == true))
219                 {
220                         _ControlOrientation coreOrientation =
221                                 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
222                                 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
223                 
224                         Rectangle temp;
225                         bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
226                         if (exist)
227                         {
228                                 pImpl->Invalidate(true);
229                         }
230                 }
231                 
232                 // Despite not changing status, it needs to rotate screen.
233                 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(__publicControl);
234                 pImplManager->RotateScreen(pControlImpl, status);
235
236                 _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
237                 if (pRootWindow)
238                 {
239                         SetRotation(*pRootWindow, __mode);
240                 }
241 //      }
242 //      else
243 //      {
244                 // [Async]
245                 // Set preffered rotation
246
247 //              _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
248 //              if (pRootWindow)
249 //              {
250 //                      SetRotation(*pRootWindow, __mode);
251 //              }
252
253                 __draw = draw;
254 //      }
255
256         SysLog(NID_UI, "[Window Manager Rotation] ---------- Update : END ----------");
257 #else           
258         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
259         SysAssert(pImplManager);
260
261         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
262         if (!pImpl)
263         {
264                 return;
265         }
266
267         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
268         if (!pEcoreEvas)
269         {
270                 return;
271         }
272
273         _Form* pForm = dynamic_cast<_Form*>(&(pImpl->GetCore()));
274         if (pForm)
275         {
276                 _Control* pParent = pForm->GetParent();
277
278                 if (pParent)
279                 {
280                         int index = pParent->GetChildIndex(*pForm);
281                         int childCount = pParent->GetChildCount();
282
283                         if (index == (childCount - 1))
284                         {
285                                 _Window* pWindow = pForm->GetRootWindow();
286                                 if (pWindow)
287                                 {
288                                         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
289                                         {
290                                                 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, true);
291                                                 pWindow->SetOrientationEnabled(true);
292                                         }
293                                         else
294                                         {
295                                                 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, false);
296                                                 pWindow->SetOrientationEnabled(false);
297                                         }
298                                 }
299                         }
300                 }
301         }
302         else
303         {
304                 _Frame* pFrame = dynamic_cast<_Frame*>(&(pImpl->GetCore()));
305                 if (pFrame)
306                 {
307                         int childCount = pFrame->GetChildCount();
308                         if (childCount == 0)
309                         {
310                                 _Window* pCurrentFrame = _ControlManager::GetInstance()->GetCurrentFrame();
311                                 if (pCurrentFrame == pFrame)
312                                 {
313                                         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
314                                         {
315                                                 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, true);
316                                                 pFrame->SetOrientationEnabled(true);
317                                         }
318                                         else
319                                         {
320                                                 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, false);
321                                                 pFrame->SetOrientationEnabled(false);
322                                         }
323                                 }
324                         }
325                 }
326         }
327
328         OrientationStatus status = pImplManager->GetOrientationStatus(__mode);
329
330         if (__updateStatus == true)
331         {
332                 __statusChanged = false;
333                 if (__status != status)
334                 {
335                         __statusChanged = true;
336                         __updateStatus = false;
337                 }
338         }
339
340         __status = status;
341
342         pEcoreEvas->AllowSetWindowBounds(false);
343         FireEvent(status);
344         pEcoreEvas->AllowSetWindowBounds(true);
345
346         // For the form to be made by Ui-Builder
347         if ((draw == true) && (__statusChanged == true))
348         {
349                 _ControlOrientation coreOrientation =
350                         (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
351                         _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
352
353                 Rectangle temp;
354                 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
355                 if (exist)
356                 {
357                         pImpl->Invalidate(true);
358                 }
359         }
360
361         // Despite not changing status, it needs to rotate screen.
362         _ControlImpl* pControlImpl = _ControlImpl::GetInstance(__publicControl);
363         pImplManager->RotateScreen(pControlImpl, status);
364 #endif
365 }
366
367 #if defined(WINDOW_BASE_ROTATE)
368 void
369 _OrientationAgent::UpdateOrientation(void)
370 {
371         // Get window rotation
372         // Update VEs
373         // Fire orientation event
374         // Update window bounds
375         // Invalidate
376
377         SysLog(NID_UI, "[Window Manager Rotation] ---------- UpdateOrientation : START ----------");
378
379         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
380         if (!pEcoreEvas)
381         {
382                 return;
383         }
384
385         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
386         if (!pImpl)
387         {
388                 return;
389         }
390
391         _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
392         if (!pRootWindow)
393         {
394                 return;
395         }
396
397         int rotation = pEcoreEvas->GetWindowRotation(*pRootWindow);
398         OrientationStatus status = ORIENTATION_STATUS_NONE;
399         switch (rotation)
400         {
401         case 0:
402                 status = ORIENTATION_STATUS_PORTRAIT;
403                 break;
404         case 270:
405                 status = ORIENTATION_STATUS_LANDSCAPE;
406                 break;
407         case 180:
408                 status = ORIENTATION_STATUS_PORTRAIT_REVERSE;
409                 break;
410         case 90:
411                 status = ORIENTATION_STATUS_LANDSCAPE_REVERSE;
412                 break;
413         default:
414                 break;
415         }
416
417         if (__updateStatus == true)
418         {
419                 __statusChanged = false;
420                 if (__status != status)
421                 {
422                         __statusChanged = true;
423                         __updateStatus = false;
424                 }
425         }
426
427         __status = status;
428
429         pEcoreEvas->AllowSetWindowBounds(false);
430         FireEvent(status);
431         pEcoreEvas->AllowSetWindowBounds(true);
432
433         // For the form to be made by Ui-Builder
434         if ((__draw == true) && (__statusChanged == true))
435         {
436                 _ControlOrientation coreOrientation =
437                         (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
438                         _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
439
440                 Rectangle temp;
441                 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
442                 if (exist)
443                 {
444                         pImpl->Invalidate(true);
445                 }
446         }
447
448         pEcoreEvas->RotateWindow(*pRootWindow, rotation);
449
450         pImpl->Invalidate(true);
451
452         Rectangle bounds = pRootWindow->GetBounds();
453         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);
454
455         SysLog(NID_UI, "[Window Manager Rotation] ---------- UpdateOrientation : END ----------");
456 }
457 #endif
458
459 void
460 _OrientationAgent::RequestOrientationEvent(void)
461 {
462         ClearLastResult();
463
464         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
465         SysTryReturnVoidResult(NID_UI, pImpl, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
466
467         unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
468         SysTryReturnVoidResult(NID_UI, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
469         pEventArgs->Construct();
470
471         unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(_REQUEST_ORIENTATION_EVENT));
472         SysTryReturnVoidResult(NID_UI, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
473
474         pEventArgs->Add(*(pString.get()));
475         
476         _UiNotificationEvent event(pImpl->GetCore().GetHandle(), pEventArgs.get());
477
478         result r = _UiEventManager::GetInstance()->PostEvent(event);
479         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
480
481         pString.release();
482         pEventArgs.release();
483 }
484
485 void
486 _OrientationAgent::FireOrientationEvent(void)
487 {
488         if (__firePublicEvent)
489         {
490                 return;
491         }
492
493         __firePublicEvent = true;
494
495         SysLog(NID_UI, "Fire the orientation event.");
496
497         if (__statusChanged)
498         {
499                 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), __status);
500                 __pPublicEvent->Fire(*pArg);
501
502                 __updateStatus = true;
503         }
504 }
505
506 void
507 _OrientationAgent::FireEvent(OrientationStatus status)
508 {
509         ClearLastResult();
510
511         _ControlManager* pCoreManager = _ControlManager::GetInstance();
512         SysAssert(pCoreManager);
513
514         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
515         if (!pImpl)
516         {
517                 return;
518         }
519
520 #if defined(WINDOW_OWNEE_PREFERRED)
521         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
522         if (!pEcoreEvas)
523         {
524                 return;
525         }
526 #endif
527
528         _ControlOrientation coreOrientation =
529                 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
530                 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
531
532         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
533         SysAssert(pImplManager);
534
535         // Core
536         pCoreManager->SetOrientation(coreOrientation);
537         pImplManager->SetOrientationStatus(status);
538         pImpl->GetCore().ChangeLayout(coreOrientation);
539
540 #if !defined(WINDOW_BASE_ROTATE)
541         // Ownee
542         int owneeCount = pImpl->GetCore().GetOwneeCount();
543         for (int i = 0; i < owneeCount; i++)
544         {
545                 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
546
547                 if (pOwnee)
548                 {
549                         pOwnee->ChangeLayout(coreOrientation);
550                 }
551         }
552 #endif
553
554 #if defined(WINDOW_OWNEE_PREFERRED)
555         int owneeCount = pImpl->GetCore().GetOwneeCount();
556         for (int i = 0; i < owneeCount; i++)
557         {
558                 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
559                 if (pOwnee)
560                 {
561                         pOwnee->ChangeLayout(coreOrientation); // Need to test
562                         pEcoreEvas->SetOwner(*pOwnee, pImpl->GetCore());
563                 }
564         }
565
566         _Control* pParent = pImpl->GetCore().GetParent();
567         if (pParent)
568         {
569                 int owneeCount = pParent->GetOwneeCount();
570                 for (int i = 0; i < owneeCount; i++)
571                 {
572                         _Window* pOwnee = pParent->GetOwnee(i);
573                         if (pOwnee)
574                         {
575                                 pOwnee->ChangeLayout(coreOrientation); // Need to test
576                                 pEcoreEvas->SetOwner(*pOwnee, *pParent);
577                         }
578                 }
579         }
580 #endif
581
582         // Public
583         if (__firePublicEvent && __statusChanged)
584         {
585                 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), status);
586                 __pPublicEvent->Fire(*pArg);
587
588                 __updateStatus = true;
589         }
590 }
591
592 #if defined(WINDOW_BASE_ROTATE)
593 void
594 _OrientationAgent::SetRotation(const _Window& window, Orientation orientation)
595 {
596         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
597         if (!pEcoreEvas)
598         {
599                 return;
600         }
601
602         switch (orientation)
603         {
604         case ORIENTATION_PORTRAIT:
605                 pEcoreEvas->SetWindowPreferredRotation(window, 0);
606                 break;
607         case ORIENTATION_LANDSCAPE:
608                 pEcoreEvas->SetWindowPreferredRotation(window, 270);
609                 break;
610         case ORIENTATION_PORTRAIT_REVERSE:
611                 pEcoreEvas->SetWindowPreferredRotation(window, 180);
612                 break;
613         case ORIENTATION_LANDSCAPE_REVERSE:
614                 pEcoreEvas->SetWindowPreferredRotation(window, 90);
615                 break;
616         case ORIENTATION_AUTOMATIC:
617                 {
618                         pEcoreEvas->SetWindowPreferredRotation(window, -1);
619                         int autoRotation[3] = {0, 90, 270};
620                         pEcoreEvas->SetWindowAvailabledRotation(window, autoRotation, 3);
621                 }
622
623                 break;
624         case ORIENTATION_AUTOMATIC_FOUR_DIRECTION:
625                 {
626                         pEcoreEvas->SetWindowPreferredRotation(window, -1);
627                         int autoFourRotation[4] = {0, 90, 180, 270};
628                         pEcoreEvas->SetWindowAvailabledRotation(window, autoFourRotation, 4);
629                 }
630
631                 break;
632         default:
633                 break;
634         }
635
636 #if !defined(WINDOW_OWNEE_PREFERRED)
637         // [Ownee]
638         // 1. ActivateWindow
639         // 2. SetOwner
640         // 3. SetRotation
641
642         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
643         if (!pImpl)
644         {
645                 return;
646         }
647
648         int owneeCount = pImpl->GetCore().GetOwneeCount();
649         for (int i = 0; i < owneeCount; i++)
650         {
651                 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
652                 if (pOwnee)
653                 {
654                         pEcoreEvas->SetOwner(*pOwnee, pImpl->GetCore());
655                 }
656         }
657
658         _Control* pParent = pImpl->GetCore().GetParent();
659         if (pParent)
660         {
661                 int owneeCount = pParent->GetOwneeCount();
662                 for (int i = 0; i < owneeCount; i++)
663                 {
664                         _Window* pOwnee = pParent->GetOwnee(i);
665                         if (pOwnee)
666                         {
667                                 pEcoreEvas->SetOwner(*pOwnee, *pParent);
668                         }
669                 }
670         }
671 #endif
672 }
673 #endif
674
675 }} // Tizen::Ui