2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
9 // http://floralicense.org/license/
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.
19 * @file FUi_OrientationAgent.cpp
20 * @brief This is the implementation file for the _OrientationAgent class.
23 #include <unique_ptr.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"
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;
50 namespace Tizen { namespace Ui {
52 const String _REQUEST_ORIENTATION_EVENT = L"RequestOrientationEvent";
55 _OrientationAgent::CreateInstanceN(Control& publicControl)
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.");
60 result r = GetLastResult();
61 SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
63 SetLastResult(E_SUCCESS);
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)
85 _PublicOrientationEvent* pPublicEvent = _PublicOrientationEvent::CreateInstanceN(publicControl);
87 result r = GetLastResult();
88 SysTryReturnVoidResult(NID_UI, pPublicEvent, r, "[%s] Propagating.", GetErrorMessage(r));
90 __pPublicEvent = pPublicEvent;
92 SetLastResult(E_SUCCESS);
95 _OrientationAgent::~_OrientationAgent(void)
99 delete __pPublicEvent;
100 __pPublicEvent = null;
105 _OrientationAgent::AddListener(IOrientationEventListener& listener)
107 result r = __pPublicEvent->AddListener(listener);
108 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
110 SetLastResult(E_SUCCESS);
114 _OrientationAgent::RemoveListener(IOrientationEventListener& listener)
116 result r = __pPublicEvent->RemoveListener(listener);
117 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
119 SetLastResult(E_SUCCESS);
123 _OrientationAgent::GetMode(void) const
129 _OrientationAgent::GetStatus(void) const
135 _OrientationAgent::SetMode(Orientation mode)
137 SysTryReturnVoidResult(NID_UI, mode != ORIENTATION_NONE, E_INVALID_ARG, "[E_INVALID_ARG] A specified input parameter is invalid.");
139 SetLastResult(E_SUCCESS);
151 _OrientationAgent::Update(bool draw)
153 #if defined(WINDOW_BASE_ROTATE)
154 _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
155 SysAssert(pImplManager);
157 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
163 // Set window rotation.
164 _Form* pForm = dynamic_cast<_Form*>(&(pImpl->GetCore()));
167 _Control* pParent = pForm->GetParent();
170 _Form* pCurrentForm = null;
171 int childCount = pParent->GetChildCount();
173 for (int i = childCount; i > 0; i--)
175 _Control* pChild = pParent->GetChild(i - 1);
177 _Form* pChildForm = dynamic_cast<_Form*>(pChild);
180 if (pChildForm->IsVisible())
182 pCurrentForm = pChildForm;
190 if (pCurrentForm == pForm)
192 _Window* pWindow = pForm->GetRootWindow();
195 Rectangle bounds = pWindow->GetBounds();
196 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x, %d, %d, %d, %d, Form] Set window rotation with mode(%d).",
197 pWindow->GetNativeHandle(), bounds.x, bounds.y, bounds.width, bounds.height, __mode);
198 SetRotation(*pWindow, __mode);
201 int owneeCount = pForm->GetOwneeCount();
202 for (int i = 0; i < owneeCount; i++)
204 _Window* pOwnee = pForm->GetOwnee(i);
208 SetRotation(*pOwnee, __mode);
217 case ORIENTATION_PORTRAIT:
220 __tempStatus = ORIENTATION_STATUS_PORTRAIT;
221 UpdateOrientation(true);
224 case ORIENTATION_LANDSCAPE:
227 __tempStatus = ORIENTATION_STATUS_LANDSCAPE;
228 UpdateOrientation(true);
229 SysLog(NID_UI, "Window Manager Rotation");
232 case ORIENTATION_PORTRAIT_REVERSE:
235 __tempStatus = ORIENTATION_STATUS_PORTRAIT_REVERSE;
236 UpdateOrientation(true);
239 case ORIENTATION_LANDSCAPE_REVERSE:
242 __tempStatus = ORIENTATION_STATUS_LANDSCAPE_REVERSE;
243 UpdateOrientation(true);
248 SysLog(NID_UI, "Window Manager Rotation Default");
256 _Frame* pFrame = dynamic_cast<_Frame*>(&(pImpl->GetCore()));
260 // Frame which has no forms
261 int childCount = pFrame->GetChildCount();
264 Rectangle bounds = pFrame->GetBounds();
265 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x, %d, %d, %d, %d, Frame] Set window rotation with mode(%d).",
266 pFrame->GetNativeHandle(), bounds.x, bounds.y, bounds.width, bounds.height, __mode);
267 SetRotation(*pFrame, __mode);
269 int owneeCount = pFrame->GetOwneeCount();
271 for (int i = 0; i < owneeCount; i++)
273 _Window* pOwnee = pFrame->GetOwnee(i);
277 SetRotation(*pOwnee, __mode);
286 _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
287 SysAssert(pImplManager);
289 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
295 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
301 _Form* pForm = dynamic_cast<_Form*>(&(pImpl->GetCore()));
304 _Control* pParent = pForm->GetParent();
308 int index = pParent->GetChildIndex(*pForm);
309 int childCount = pParent->GetChildCount();
311 if (index == (childCount - 1))
313 _Window* pWindow = pForm->GetRootWindow();
316 if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
318 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, true);
319 pWindow->SetOrientationEnabled(true);
323 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, false);
324 pWindow->SetOrientationEnabled(false);
332 _Frame* pFrame = dynamic_cast<_Frame*>(&(pImpl->GetCore()));
335 int childCount = pFrame->GetChildCount();
338 _Window* pCurrentFrame = _ControlManager::GetInstance()->GetCurrentFrame();
339 if (pCurrentFrame == pFrame)
341 if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
343 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, true);
344 pFrame->SetOrientationEnabled(true);
348 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, false);
349 pFrame->SetOrientationEnabled(false);
356 OrientationStatus status = pImplManager->GetOrientationStatus(__mode);
358 if (__updateStatus == true)
360 __statusChanged = false;
361 if (__status != status)
363 __statusChanged = true;
364 __updateStatus = false;
370 pEcoreEvas->AllowSetWindowBounds(false);
372 pEcoreEvas->AllowSetWindowBounds(true);
374 // For the form to be made by Ui-Builder
375 if ((draw == true) && (__statusChanged == true))
377 _ControlOrientation coreOrientation =
378 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
379 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
382 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
385 pImpl->Invalidate(true);
389 // Despite not changing status, it needs to rotate screen.
390 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(__publicControl);
391 pImplManager->RotateScreen(pControlImpl, status);
395 #if defined(WINDOW_BASE_ROTATE)
397 _OrientationAgent::UpdateOrientation(bool force)
399 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
405 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
413 _Window* pWindow = pImpl->GetCore().GetRootWindow();
416 rotation = pEcoreEvas->GetWindowRotation(*pWindow);
419 // Update evas objects.
420 OrientationStatus status = ORIENTATION_STATUS_NONE;
424 status = ORIENTATION_STATUS_PORTRAIT;
427 status = ORIENTATION_STATUS_LANDSCAPE;
430 status = ORIENTATION_STATUS_PORTRAIT_REVERSE;
433 status = ORIENTATION_STATUS_LANDSCAPE_REVERSE;
441 status = __tempStatus;
444 if (__updateStatus == true)
446 __statusChanged = false;
447 if (__status != status)
449 __statusChanged = true;
450 __updateStatus = false;
456 pEcoreEvas->AllowSetWindowBounds(false);
458 pEcoreEvas->AllowSetWindowBounds(true);
460 // For the form to be made by Ui-Builder
461 if ((__draw == true) && (__statusChanged == true))
463 _ControlOrientation coreOrientation =
464 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
465 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
468 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
471 pImpl->Invalidate(true);
475 _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
478 pEcoreEvas->UpdateWindowBounds(*pRootWindow);
480 pImpl->Invalidate(true);
482 Rectangle bounds = pRootWindow->GetBounds();
483 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x, %d, %d, %d, %d] Update VEs to %d degree.",
484 pRootWindow->GetNativeHandle(), bounds.x, bounds.y, bounds.width, bounds.height, rotation);
490 _OrientationAgent::RequestOrientationEvent(void)
494 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
495 SysTryReturnVoidResult(NID_UI, pImpl, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
497 unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
498 SysTryReturnVoidResult(NID_UI, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
499 pEventArgs->Construct();
501 unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(_REQUEST_ORIENTATION_EVENT));
502 SysTryReturnVoidResult(NID_UI, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
504 pEventArgs->Add(*(pString.get()));
506 _UiNotificationEvent event(pImpl->GetCore().GetHandle(), pEventArgs.get());
508 result r = _UiEventManager::GetInstance()->PostEvent(event);
509 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
512 pEventArgs.release();
516 _OrientationAgent::FireOrientationEvent(void)
518 if (__firePublicEvent)
523 __firePublicEvent = true;
525 SysLog(NID_UI, "Fire the orientation event.");
529 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), __status);
530 __pPublicEvent->Fire(*pArg);
532 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
535 _Window* pWindow = pImpl->GetCore().GetRootWindow();
538 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x] Fire the public orientation event..", pWindow->GetNativeHandle());
542 __updateStatus = true;
547 _OrientationAgent::FireEvent(OrientationStatus status)
551 _ControlManager* pCoreManager = _ControlManager::GetInstance();
552 SysAssert(pCoreManager);
554 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
560 _ControlOrientation coreOrientation =
561 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
562 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
564 _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
565 SysAssert(pImplManager);
568 pCoreManager->SetOrientation(coreOrientation);
569 pImplManager->SetOrientationStatus(status);
570 pImpl->GetCore().ChangeLayout(coreOrientation);
572 #if !defined(WINDOW_BASE_ROTATE)
574 int owneeCount = pImpl->GetCore().GetOwneeCount();
575 for (int i = 0; i < owneeCount; i++)
577 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
581 pOwnee->ChangeLayout(coreOrientation);
587 if (__firePublicEvent && __statusChanged)
589 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), status);
590 __pPublicEvent->Fire(*pArg);
592 _Window* pWindow = pImpl->GetCore().GetRootWindow();
595 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x] Fire the public orientation event..", pWindow->GetNativeHandle());
598 __updateStatus = true;
602 #if defined(WINDOW_BASE_ROTATE)
604 _OrientationAgent::SetRotation(const _Window& window, Orientation orientation)
606 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
612 int deviceOrientation = app_get_device_orientation();
613 int windowRotation = pEcoreEvas->GetWindowRotation(window);
615 bool callback = true;
617 // Decide updating orientation forcibly.
620 case ORIENTATION_PORTRAIT:
622 pEcoreEvas->SetWindowPreferredRotation(window, 0);
624 __tempStatus = ORIENTATION_STATUS_PORTRAIT;
625 UpdateOrientation(true);
630 if ((deviceOrientation == 0) || (windowRotation == 0))
637 case ORIENTATION_LANDSCAPE:
639 pEcoreEvas->SetWindowPreferredRotation(window, 270);
641 __tempStatus = ORIENTATION_STATUS_LANDSCAPE;
642 UpdateOrientation(true);
647 if ((deviceOrientation == 270) || (windowRotation == 270))
654 case ORIENTATION_PORTRAIT_REVERSE:
656 pEcoreEvas->SetWindowPreferredRotation(window, 180);
658 __tempStatus = ORIENTATION_STATUS_PORTRAIT_REVERSE;
659 UpdateOrientation(true);
664 if ((deviceOrientation == 180) || (windowRotation == 180))
671 case ORIENTATION_LANDSCAPE_REVERSE:
673 pEcoreEvas->SetWindowPreferredRotation(window, 90);
675 __tempStatus = ORIENTATION_STATUS_LANDSCAPE_REVERSE;
676 UpdateOrientation(true);
681 if ((deviceOrientation == 90) || (windowRotation == 90))
688 case ORIENTATION_AUTOMATIC:
690 pEcoreEvas->SetWindowPreferredRotation(window, -1);
692 int autoRotation[3] = {0, 90, 270};
693 pEcoreEvas->SetWindowAvailabledRotation(window, autoRotation, 3);
695 if (deviceOrientation == windowRotation)
701 if (deviceOrientation == 180)
708 case ORIENTATION_AUTOMATIC_FOUR_DIRECTION:
710 pEcoreEvas->SetWindowPreferredRotation(window, -1);
712 int autoFourRotation[4] = {0, 90, 180, 270};
713 pEcoreEvas->SetWindowAvailabledRotation(window, autoFourRotation, 4);
715 if (deviceOrientation == windowRotation)
725 if (callback == false)