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-based 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-based 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 Rectangle bounds = pRootWindow->GetBounds();
429 SysLog(NID_UI, "[Window-based Rotation][Window : 0x%x, %d, %d, %d, %d] Update evas objects to %d degree.",
430 pRootWindow->GetNativeHandle(), bounds.x, bounds.y, bounds.width, bounds.height, rotation);
436 _OrientationAgent::RequestOrientationEvent(void)
440 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
441 SysTryReturnVoidResult(NID_UI, pImpl, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
443 unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
444 SysTryReturnVoidResult(NID_UI, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
445 pEventArgs->Construct();
447 unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(_REQUEST_ORIENTATION_EVENT));
448 SysTryReturnVoidResult(NID_UI, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
450 pEventArgs->Add(*(pString.get()));
452 _UiNotificationEvent event(pImpl->GetCore().GetHandle(), pEventArgs.get());
454 result r = _UiEventManager::GetInstance()->PostEvent(event);
455 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
458 pEventArgs.release();
462 _OrientationAgent::FireOrientationEvent(void)
464 if (__firePublicEvent)
469 __firePublicEvent = true;
471 SysLog(NID_UI, "Fire the orientation event.");
475 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), __status);
476 __pPublicEvent->Fire(*pArg);
478 __updateStatus = true;
483 _OrientationAgent::FireEvent(OrientationStatus status)
487 _ControlManager* pCoreManager = _ControlManager::GetInstance();
488 SysAssert(pCoreManager);
490 _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
496 _ControlOrientation coreOrientation =
497 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
498 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
500 _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
501 SysAssert(pImplManager);
504 pCoreManager->SetOrientation(coreOrientation);
505 pImplManager->SetOrientationStatus(status);
506 pImpl->GetCore().ChangeLayout(coreOrientation);
508 #if !defined(WINDOW_BASE_ROTATE)
510 int owneeCount = pImpl->GetCore().GetOwneeCount();
511 for (int i = 0; i < owneeCount; i++)
513 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
517 pOwnee->ChangeLayout(coreOrientation);
523 if (__firePublicEvent && __statusChanged)
525 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), status);
526 __pPublicEvent->Fire(*pArg);
528 __updateStatus = true;
532 #if defined(WINDOW_BASE_ROTATE)
534 _OrientationAgent::SetRotation(const _Window& window, Orientation orientation)
536 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
542 int deviceOrientation = app_get_device_orientation();
543 int windowRotation = pEcoreEvas->GetWindowRotation(window);
545 bool callback = true;
547 // Decide updating orientation forcibly.
550 case ORIENTATION_PORTRAIT:
551 pEcoreEvas->SetWindowPreferredRotation(window, 0);
553 if ((deviceOrientation == 0) || (windowRotation == 0))
559 case ORIENTATION_LANDSCAPE:
560 pEcoreEvas->SetWindowPreferredRotation(window, 270);
562 if ((deviceOrientation == 270) || (windowRotation == 270))
568 case ORIENTATION_PORTRAIT_REVERSE:
569 pEcoreEvas->SetWindowPreferredRotation(window, 180);
571 if ((deviceOrientation == 180) || (windowRotation == 180))
577 case ORIENTATION_LANDSCAPE_REVERSE:
578 pEcoreEvas->SetWindowPreferredRotation(window, 90);
580 if ((deviceOrientation == 90) || (windowRotation == 90))
586 case ORIENTATION_AUTOMATIC:
588 pEcoreEvas->SetWindowPreferredRotation(window, -1);
590 int autoRotation[3] = {0, 90, 270};
591 pEcoreEvas->SetWindowAvailabledRotation(window, autoRotation, 3);
593 if (deviceOrientation == windowRotation)
599 if (deviceOrientation == 180)
606 case ORIENTATION_AUTOMATIC_FOUR_DIRECTION:
608 pEcoreEvas->SetWindowPreferredRotation(window, -1);
610 int autoFourRotation[4] = {0, 90, 180, 270};
611 pEcoreEvas->SetWindowAvailabledRotation(window, autoFourRotation, 4);
613 if (deviceOrientation == windowRotation)
623 if (callback == false)