Merge "Bug fix in GetfallbackFont , check same style font" into tizen_2.1
[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 <FBaseSysLog.h>
25 #include <FBaseColArrayList.h>
26 #include "FUi_OrientationAgent.h"
27 #include "FUi_ControlManager.h"
28 #include "FUi_ControlImplManager.h"
29 #include "FUi_PublicOrientationEvent.h"
30 #include "FUi_ControlImpl.h"
31 #include "FUi_Window.h"
32 #include "FUiCtrl_FormImpl.h"
33 #include "FUiCtrl_FrameImpl.h"
34 #include "FUiCtrl_Frame.h"
35 #include "FUiCtrl_Form.h"
36 #include "FUi_EcoreEvasMgr.h"
37 #include "FUi_EcoreEvas.h"
38 #include "FUi_ControlManager.h"
39 #include "FUi_UiNotificationEvent.h"
40 #include "FUi_UiEventManager.h"
41
42 using namespace std;
43 using namespace Tizen::Base;
44 using namespace Tizen::Base::Collection;
45 using namespace Tizen::Base::Runtime;
46 using namespace Tizen::Ui::Controls;
47 using namespace Tizen::Graphics;
48
49 namespace Tizen { namespace Ui {
50
51 const String _REQUEST_ORIENTATION_EVENT = L"RequestOrientationEvent";
52
53 _OrientationAgent*
54 _OrientationAgent::CreateInstanceN(Control& publicControl)
55 {
56         _OrientationAgent* pAgent = new (std::nothrow) _OrientationAgent(publicControl);
57         SysTryReturn(NID_UI, pAgent, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
58
59         result r = GetLastResult();
60         SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
61
62         SetLastResult(E_SUCCESS);
63
64         return pAgent;
65
66 CATCH:
67         delete pAgent;
68         return null;
69 }
70
71 _OrientationAgent::_OrientationAgent(Control& publicControl)
72         : __publicControl(publicControl)
73         , __pPublicEvent(null)
74         , __mode(ORIENTATION_PORTRAIT)
75         , __status(ORIENTATION_STATUS_PORTRAIT)
76         , __firePublicEvent(false)
77         , __statusChanged(false)
78         , __updateStatus(true)
79 {
80         _PublicOrientationEvent* pPublicEvent = _PublicOrientationEvent::CreateInstanceN(publicControl);
81
82         result r = GetLastResult();
83         SysTryReturnVoidResult(NID_UI, pPublicEvent, r, "[%s] Propagating.", GetErrorMessage(r));
84
85         __pPublicEvent = pPublicEvent;
86
87         SetLastResult(E_SUCCESS);
88 }
89
90 _OrientationAgent::~_OrientationAgent(void)
91 {
92         if (__pPublicEvent)
93         {
94                 delete __pPublicEvent;
95                 __pPublicEvent = null;
96         }
97 }
98
99 void
100 _OrientationAgent::AddListener(IOrientationEventListener& listener)
101 {
102         result r = __pPublicEvent->AddListener(listener);
103         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
104
105         SetLastResult(E_SUCCESS);
106 }
107
108 void
109 _OrientationAgent::RemoveListener(IOrientationEventListener& listener)
110 {
111         result r = __pPublicEvent->RemoveListener(listener);
112         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
113
114         SetLastResult(E_SUCCESS);
115 }
116
117 Orientation
118 _OrientationAgent::GetMode(void) const
119 {
120         return __mode;
121 }
122
123 OrientationStatus
124 _OrientationAgent::GetStatus(void) const
125 {
126         return __status;
127 }
128
129 void
130 _OrientationAgent::SetMode(Orientation mode)
131 {
132         SysTryReturnVoidResult(NID_UI, mode != ORIENTATION_NONE, E_INVALID_ARG, "[E_INVALID_ARG] A specified input parameter is invalid.");
133
134         SetLastResult(E_SUCCESS);
135
136         if (__mode == mode)
137         {
138                 return;
139         }
140
141         __mode = mode;
142         Update();
143 }
144
145 void
146 _OrientationAgent::Update(bool draw)
147 {
148         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
149         SysAssert(pImplManager);
150
151         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
152         if (!pImpl)
153         {
154                 return;
155         }
156
157         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
158         if (!pEcoreEvas)
159         {
160                 return;
161         }
162
163         _Form* pForm = dynamic_cast<_Form*>(&(pImpl->GetCore()));
164         if (pForm)
165         {
166                 _Control* pParent = pForm->GetParent();
167
168                 if (pParent)
169                 {
170                         int index = pParent->GetChildIndex(*pForm);
171                         int childCount = pParent->GetChildCount();
172
173                         if (index == (childCount - 1))
174                         {
175                                 _Window* pWindow = pForm->GetRootWindow();
176                                 if (pWindow)
177                                 {
178                                         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
179                                         {
180                                                 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, true);
181                                                 pWindow->SetOrientationEnabled(true);
182                                         }
183                                         else
184                                         {
185                                                 pEcoreEvas->SetWindowOrientationEnabled(*pWindow, false);
186                                                 pWindow->SetOrientationEnabled(false);
187                                         }
188                                 }
189                         }
190                 }
191         }
192         else
193         {
194                 _Frame* pFrame = dynamic_cast<_Frame*>(&(pImpl->GetCore()));
195                 if (pFrame)
196                 {
197                         int childCount = pFrame->GetChildCount();
198                         if (childCount == 0)
199                         {
200                                 _Window* pCurrentFrame = _ControlManager::GetInstance()->GetCurrentFrame();
201                                 if (pCurrentFrame == pFrame)
202                                 {
203                                         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
204                                         {
205                                                 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, true);
206                                                 pFrame->SetOrientationEnabled(true);
207                                         }
208                                         else
209                                         {
210                                                 pEcoreEvas->SetWindowOrientationEnabled(*pFrame, false);
211                                                 pFrame->SetOrientationEnabled(false);
212                                         }
213                                 }
214                         }
215                 }
216         }
217
218         OrientationStatus status = pImplManager->GetOrientationStatus(__mode);
219
220         if (__updateStatus == true)
221         {
222                 __statusChanged = false;
223                 if (__status != status)
224                 {
225                         __statusChanged = true;
226                         __updateStatus = false;
227                 }
228         }
229
230         __status = status;
231
232         pEcoreEvas->AllowSetWindowBounds(false);
233         FireEvent(status);
234         pEcoreEvas->AllowSetWindowBounds(true);
235
236         // For the form to be made by Ui-Builder
237         if ((draw == true) && (__statusChanged == true))
238         {
239                 _ControlOrientation coreOrientation =
240                         (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
241                         _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
242
243                 Rectangle temp;
244                 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
245                 if (exist)
246                 {
247                         pImpl->Invalidate(true);
248                 }
249         }
250
251         // Despite not changing status, it needs to rotate screen.
252         _ControlImpl* pControlImpl = _ControlImpl::GetInstance(__publicControl);
253         pImplManager->RotateScreen(pControlImpl, status);
254 }
255
256 void
257 _OrientationAgent::RequestOrientationEvent(void)
258 {
259         ClearLastResult();
260
261         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
262         SysTryReturnVoidResult(NID_UI, pImpl, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
263
264         unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
265         SysTryReturnVoidResult(NID_UI, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
266         pEventArgs->Construct();
267
268         unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(_REQUEST_ORIENTATION_EVENT));
269         SysTryReturnVoidResult(NID_UI, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
270
271         pEventArgs->Add(*(pString.get()));
272         
273         _UiNotificationEvent event(pImpl->GetCore().GetHandle(), pEventArgs.get());
274
275         result r = _UiEventManager::GetInstance()->PostEvent(event);
276         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
277
278         pString.release();
279         pEventArgs.release();
280 }
281
282 void
283 _OrientationAgent::FireOrientationEvent(void)
284 {
285         if (__firePublicEvent)
286         {
287                 return;
288         }
289
290         __firePublicEvent = true;
291
292         SysLog(NID_UI, "Fire the orientation event.");
293
294         if (__statusChanged)
295         {
296                 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), __status);
297                 __pPublicEvent->Fire(*pArg);
298
299                 __updateStatus = true;
300         }
301 }
302
303 void
304 _OrientationAgent::FireEvent(OrientationStatus status)
305 {
306         ClearLastResult();
307
308         _ControlManager* pCoreManager = _ControlManager::GetInstance();
309         SysAssert(pCoreManager);
310
311         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
312         if (!pImpl)
313         {
314                 return;
315         }
316
317         _ControlOrientation coreOrientation =
318                 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
319                 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
320
321         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
322         SysAssert(pImplManager);
323
324         // Core
325         pCoreManager->SetOrientation(coreOrientation);
326         pImplManager->SetOrientationStatus(status);
327         pImpl->GetCore().ChangeLayout(coreOrientation);
328
329         // Ownee
330         int owneeCount = pImpl->GetCore().GetOwneeCount();
331         for (int i = 0; i < owneeCount; i++)
332         {
333                 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
334
335                 if (pOwnee)
336                 {
337                         pOwnee->ChangeLayout(coreOrientation);
338                 }
339         }
340
341         // Public
342         if (__firePublicEvent && __statusChanged)
343         {
344                 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), status);
345                 __pPublicEvent->Fire(*pArg);
346
347                 __updateStatus = true;
348         }
349 }
350
351 }} // Tizen::Ui