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 , __firePublicEvent(false)
78 , __statusChanged(false)
79 , __updateStatus(true)
80 #if defined(WINDOW_BASE_ROTATE)
84 _PublicOrientationEvent* pPublicEvent = _PublicOrientationEvent::CreateInstanceN(publicControl);
86 result r = GetLastResult();
87 SysTryReturnVoidResult(NID_UI, pPublicEvent, r, "[%s] Propagating.", GetErrorMessage(r));
89 __pPublicEvent = pPublicEvent;
91 SetLastResult(E_SUCCESS);
94 _OrientationAgent::~_OrientationAgent(void)
98 delete __pPublicEvent;
99 __pPublicEvent = null;
104 _OrientationAgent::AddListener(IOrientationEventListener& listener)
106 result r = __pPublicEvent->AddListener(listener);
107 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
109 SetLastResult(E_SUCCESS);
113 _OrientationAgent::RemoveListener(IOrientationEventListener& listener)
115 result r = __pPublicEvent->RemoveListener(listener);
116 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
118 SetLastResult(E_SUCCESS);
122 _OrientationAgent::GetMode(void) const
128 _OrientationAgent::GetStatus(void) const
134 _OrientationAgent::SetMode(Orientation mode)
136 SysTryReturnVoidResult(NID_UI, mode != ORIENTATION_NONE, E_INVALID_ARG, "[E_INVALID_ARG] A specified input parameter is invalid.");
138 SetLastResult(E_SUCCESS);
150 _OrientationAgent::Update(bool draw)
152 #if defined(WINDOW_BASE_ROTATE)
153 _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
154 SysAssert(pImplManager);
156 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
162 // Set window rotation.
163 _Form* pForm = dynamic_cast<_Form*>(&(pImpl->GetCore()));
166 _Control* pParent = pForm->GetParent();
169 _Form* pCurrentForm = null;
170 int childCount = pParent->GetChildCount();
172 for (int i = childCount; i > 0; i--)
174 _Control* pChild = pParent->GetChild(i - 1);
176 _Form* pChildForm = dynamic_cast<_Form*>(pChild);
179 if (pChildForm->IsVisible())
181 pCurrentForm = pChildForm;
189 if (pCurrentForm == pForm)
191 _Window* pWindow = pForm->GetRootWindow();
194 Rectangle bounds = pWindow->GetBounds();
195 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x, %d, %d, %d, %d, Form] Set window rotation with mode(%d).",
196 pWindow->GetNativeHandle(), bounds.x, bounds.y, bounds.width, bounds.height, __mode);
197 SetRotation(*pWindow, __mode);
200 int owneeCount = pForm->GetOwneeCount();
201 for (int i = 0; i < owneeCount; i++)
203 _Window* pOwnee = pForm->GetOwnee(i);
207 SetRotation(*pOwnee, __mode);
215 _Frame* pFrame = dynamic_cast<_Frame*>(&(pImpl->GetCore()));
219 // Frame which has no forms
220 int childCount = pFrame->GetChildCount();
223 Rectangle bounds = pFrame->GetBounds();
224 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x, %d, %d, %d, %d, Frame] Set window rotation with mode(%d).",
225 pFrame->GetNativeHandle(), bounds.x, bounds.y, bounds.width, bounds.height, __mode);
226 SetRotation(*pFrame, __mode);
228 int owneeCount = pFrame->GetOwneeCount();
230 for (int i = 0; i < owneeCount; i++)
232 _Window* pOwnee = pFrame->GetOwnee(i);
236 SetRotation(*pOwnee, __mode);
245 _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
246 SysAssert(pImplManager);
248 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
254 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
260 _Form* pForm = dynamic_cast<_Form*>(&(pImpl->GetCore()));
263 _Control* pParent = pForm->GetParent();
267 int index = pParent->GetChildIndex(*pForm);
268 int childCount = pParent->GetChildCount();
270 if (index == (childCount - 1))
272 _Window* pWindow = pForm->GetRootWindow();
275 if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
277 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, true);
278 pWindow->SetOrientationEnabled(true);
282 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, false);
283 pWindow->SetOrientationEnabled(false);
291 _Frame* pFrame = dynamic_cast<_Frame*>(&(pImpl->GetCore()));
294 int childCount = pFrame->GetChildCount();
297 _Window* pCurrentFrame = _ControlManager::GetInstance()->GetCurrentFrame();
298 if (pCurrentFrame == pFrame)
300 if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
302 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, true);
303 pFrame->SetOrientationEnabled(true);
307 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, false);
308 pFrame->SetOrientationEnabled(false);
315 OrientationStatus status = pImplManager->GetOrientationStatus(__mode);
317 if (__updateStatus == true)
319 __statusChanged = false;
320 if (__status != status)
322 __statusChanged = true;
323 __updateStatus = false;
329 pEcoreEvas->AllowSetWindowBounds(false);
331 pEcoreEvas->AllowSetWindowBounds(true);
333 // For the form to be made by Ui-Builder
334 if ((draw == true) && (__statusChanged == true))
336 _ControlOrientation coreOrientation =
337 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
338 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
341 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
344 pImpl->Invalidate(true);
348 // Despite not changing status, it needs to rotate screen.
349 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(__publicControl);
350 pImplManager->RotateScreen(pControlImpl, status);
354 #if defined(WINDOW_BASE_ROTATE)
356 _OrientationAgent::UpdateOrientation(void)
358 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
364 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
370 int rotation = pEcoreEvas->GetWindowRotation(*(pImpl->GetCore().GetRootWindow()));
372 // Update evas objects.
373 OrientationStatus status = ORIENTATION_STATUS_NONE;
377 status = ORIENTATION_STATUS_PORTRAIT;
380 status = ORIENTATION_STATUS_LANDSCAPE;
383 status = ORIENTATION_STATUS_PORTRAIT_REVERSE;
386 status = ORIENTATION_STATUS_LANDSCAPE_REVERSE;
392 if (__updateStatus == true)
394 __statusChanged = false;
395 if (__status != status)
397 __statusChanged = true;
398 __updateStatus = false;
404 pEcoreEvas->AllowSetWindowBounds(false);
406 pEcoreEvas->AllowSetWindowBounds(true);
408 // For the form to be made by Ui-Builder
409 if ((__draw == true) && (__statusChanged == true))
411 _ControlOrientation coreOrientation =
412 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
413 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
416 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
419 pImpl->Invalidate(true);
423 _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
426 pEcoreEvas->UpdateWindowBounds(*pRootWindow);
428 pImpl->Invalidate(true);
430 Rectangle bounds = pRootWindow->GetBounds();
431 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x, %d, %d, %d, %d] Update VEs to %d degree.",
432 pRootWindow->GetNativeHandle(), bounds.x, bounds.y, bounds.width, bounds.height, rotation);
438 _OrientationAgent::RequestOrientationEvent(void)
442 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
443 SysTryReturnVoidResult(NID_UI, pImpl, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
445 unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
446 SysTryReturnVoidResult(NID_UI, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
447 pEventArgs->Construct();
449 unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(_REQUEST_ORIENTATION_EVENT));
450 SysTryReturnVoidResult(NID_UI, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
452 pEventArgs->Add(*(pString.get()));
454 _UiNotificationEvent event(pImpl->GetCore().GetHandle(), pEventArgs.get());
456 result r = _UiEventManager::GetInstance()->PostEvent(event);
457 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
460 pEventArgs.release();
464 _OrientationAgent::FireOrientationEvent(void)
466 if (__firePublicEvent)
471 __firePublicEvent = true;
473 SysLog(NID_UI, "Fire the orientation event.");
477 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), __status);
478 __pPublicEvent->Fire(*pArg);
480 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
483 _Window* pWindow = pImpl->GetCore().GetRootWindow();
486 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x] Fire the public orientation event..", pWindow->GetNativeHandle());
490 __updateStatus = true;
495 _OrientationAgent::FireEvent(OrientationStatus status)
499 _ControlManager* pCoreManager = _ControlManager::GetInstance();
500 SysAssert(pCoreManager);
502 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
508 _ControlOrientation coreOrientation =
509 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
510 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
512 _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
513 SysAssert(pImplManager);
516 pCoreManager->SetOrientation(coreOrientation);
517 pImplManager->SetOrientationStatus(status);
518 pImpl->GetCore().ChangeLayout(coreOrientation);
520 #if !defined(WINDOW_BASE_ROTATE)
522 int owneeCount = pImpl->GetCore().GetOwneeCount();
523 for (int i = 0; i < owneeCount; i++)
525 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
529 pOwnee->ChangeLayout(coreOrientation);
535 if (__firePublicEvent && __statusChanged)
537 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), status);
538 __pPublicEvent->Fire(*pArg);
540 _Window* pWindow = pImpl->GetCore().GetRootWindow();
543 SysLog(NID_UI, "[Window Manager Rotation][Window : 0x%x] Fire the public orientation event..", pWindow->GetNativeHandle());
546 __updateStatus = true;
550 #if defined(WINDOW_BASE_ROTATE)
552 _OrientationAgent::SetRotation(const _Window& window, Orientation orientation)
554 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
560 int deviceOrientation = app_get_device_orientation();
561 int windowRotation = pEcoreEvas->GetWindowRotation(window);
563 bool callback = true;
565 // Decide updating orientation forcibly.
568 case ORIENTATION_PORTRAIT:
569 pEcoreEvas->SetWindowPreferredRotation(window, 0);
571 if ((deviceOrientation == 0) || (windowRotation == 0))
577 case ORIENTATION_LANDSCAPE:
578 pEcoreEvas->SetWindowPreferredRotation(window, 270);
580 if ((deviceOrientation == 270) || (windowRotation == 270))
586 case ORIENTATION_PORTRAIT_REVERSE:
587 pEcoreEvas->SetWindowPreferredRotation(window, 180);
589 if ((deviceOrientation == 180) || (windowRotation == 180))
595 case ORIENTATION_LANDSCAPE_REVERSE:
596 pEcoreEvas->SetWindowPreferredRotation(window, 90);
598 if ((deviceOrientation == 90) || (windowRotation == 90))
604 case ORIENTATION_AUTOMATIC:
606 pEcoreEvas->SetWindowPreferredRotation(window, -1);
608 int autoRotation[3] = {0, 90, 270};
609 pEcoreEvas->SetWindowAvailabledRotation(window, autoRotation, 3);
611 if (deviceOrientation == windowRotation)
617 if (deviceOrientation == 180)
624 case ORIENTATION_AUTOMATIC_FOUR_DIRECTION:
626 pEcoreEvas->SetWindowPreferredRotation(window, -1);
628 int autoFourRotation[4] = {0, 90, 180, 270};
629 pEcoreEvas->SetWindowAvailabledRotation(window, autoFourRotation, 4);
631 if (deviceOrientation == windowRotation)
641 if (callback == false)