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