Changed indicator bg color.
[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.1 (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 #include "FUi_TouchManager.h"
43
44 using namespace std;
45 using namespace Tizen::Base;
46 using namespace Tizen::Base::Collection;
47 using namespace Tizen::Base::Runtime;
48 using namespace Tizen::Ui::Controls;
49 using namespace Tizen::Graphics;
50
51 namespace
52 {
53 const wchar_t* _REQUEST_ORIENTATION_EVENT = L"RequestOrientationEvent";
54 }
55
56 namespace Tizen { namespace Ui {
57
58 _OrientationAgent*
59 _OrientationAgent::CreateInstanceN(Control& publicControl)
60 {
61         _OrientationAgent* pAgent = new (std::nothrow) _OrientationAgent(publicControl);
62         SysTryReturn(NID_UI, pAgent, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
63
64         result r = GetLastResult();
65         SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
66
67         SetLastResult(E_SUCCESS);
68
69         return pAgent;
70
71 CATCH:
72         delete pAgent;
73         return null;
74 }
75
76 _OrientationAgent::_OrientationAgent(Control& publicControl)
77         : __publicControl(publicControl)
78         , __pPublicEvent(null)
79         , __mode(ORIENTATION_PORTRAIT)
80         , __status(ORIENTATION_STATUS_PORTRAIT)
81         , __tempStatus(ORIENTATION_STATUS_PORTRAIT)
82         , __firePublicEvent(false)
83         , __statusChanged(false)
84         , __updateStatus(true)
85         , __draw(false)
86 {
87         _PublicOrientationEvent* pPublicEvent = _PublicOrientationEvent::CreateInstanceN(publicControl);
88
89         result r = GetLastResult();
90         SysTryReturnVoidResult(NID_UI, pPublicEvent, r, "[%s] Propagating.", GetErrorMessage(r));
91
92         __pPublicEvent = pPublicEvent;
93
94         SetLastResult(E_SUCCESS);
95 }
96
97 _OrientationAgent::~_OrientationAgent(void)
98 {
99         if (__pPublicEvent)
100         {
101                 delete __pPublicEvent;
102                 __pPublicEvent = null;
103         }
104 }
105
106 void
107 _OrientationAgent::AddListener(IOrientationEventListener& listener)
108 {
109         result r = __pPublicEvent->AddListener(listener);
110         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
111
112         SetLastResult(E_SUCCESS);
113 }
114
115 void
116 _OrientationAgent::RemoveListener(IOrientationEventListener& listener)
117 {
118         result r = __pPublicEvent->RemoveListener(listener);
119         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
120
121         SetLastResult(E_SUCCESS);
122 }
123
124 Orientation
125 _OrientationAgent::GetMode(void) const
126 {
127         return __mode;
128 }
129
130 OrientationStatus
131 _OrientationAgent::GetStatus(void) const
132 {
133         return __status;
134 }
135
136 void
137 _OrientationAgent::SetMode(Orientation mode)
138 {
139         SysTryReturnVoidResult(NID_UI, mode != ORIENTATION_NONE, E_INVALID_ARG, "[E_INVALID_ARG] A specified input parameter is invalid.");
140
141         SetLastResult(E_SUCCESS);
142
143         if (__mode == mode)
144         {
145                 return;
146         }
147
148         __mode = mode;
149         Update();
150 }
151
152 void
153 _OrientationAgent::Update(bool draw)
154 {
155         // Update orientation status(Not Auto-mode)
156         // Request rotation to window manager -> async -> Update VEs
157         // Window(not rotation) -> sync -> UpdateVEs
158
159         SysLog(NID_UI, "[WM ROTATION][AGENT 0x%x] ---------- Update : START ----------", this);
160
161         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
162         SysAssert(pImplManager);
163
164         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
165         if (!pImpl)
166         {
167                 return;
168         }
169
170         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
171         if (!pEcoreEvas)
172         {
173                 return;
174         }
175
176         bool autoMode = false;
177
178         if ((__mode == ORIENTATION_AUTOMATIC) || (__mode == ORIENTATION_AUTOMATIC_FOUR_DIRECTION))
179         {
180                 autoMode = true;
181         }
182
183 //      if (autoMode == false)
184 //      {
185                 // [Sync]
186                 // Update orientation status
187                 // Update VEs
188                 // Fire orientation event
189                 // Rotate screen
190                 // Set preffered rotation
191
192                 _Window* pWindow = pImpl->GetCore().GetRootWindow();
193                 NativeWindowHandle handle = 0;
194                 if (pWindow)
195                 {
196                         handle = pWindow->GetNativeHandle();
197                 }
198
199                 OrientationStatus status = pImplManager->GetOrientationStatus(__mode);
200                 SysLog(NID_UI, "[WM ROTATION][AGENT 0x%x][WIN 0x%x] Update : __mode(%d) -> status(%d)", this, handle, __mode, status);
201
202                 if (__updateStatus == true)
203                 {
204                         __statusChanged = false;
205                         if (__status != status)
206                         {
207                                 __statusChanged = true;
208                                 __updateStatus = false;
209                         }
210                 }
211
212                 __status = status;
213
214                 pEcoreEvas->AllowSetWindowBounds(false);
215                 FireEvent(status);
216                 pEcoreEvas->AllowSetWindowBounds(true);
217
218                 // For the form to be made by Ui-Builder
219                 if ((draw == true) && (__statusChanged == true))
220                 {
221                         _ControlOrientation coreOrientation =
222                                 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
223                                 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
224
225                         Rectangle temp;
226                         bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
227                         if (exist)
228                         {
229                                 pImpl->Invalidate(true);
230                         }
231                 }
232
233                 // Despite not changing status, it needs to rotate screen.
234                 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(__publicControl);
235                 pImplManager->RotateScreen(pControlImpl, status);
236
237                 _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
238                 if (pRootWindow)
239                 {
240                         SetRotation(*pRootWindow, __mode);
241                 }
242 //      }
243 //      else
244 //      {
245                 // [Async]
246                 // Set preffered rotation
247
248 //              _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
249 //              if (pRootWindow)
250 //              {
251 //                      SetRotation(*pRootWindow, __mode);
252 //              }
253
254                 __draw = draw;
255 //      }
256
257         SysLog(NID_UI, "[WM ROTATION][AGENT 0x%x] ---------- Update : END ----------", this);
258 }
259
260 void
261 _OrientationAgent::UpdateOrientation(void)
262 {
263         // Get window rotation
264         // Update VEs
265         // Fire orientation event
266         // Update window bounds
267         // Invalidate
268
269         SysLog(NID_UI, "[WM ROTATION][AGENT 0x%x] ---------- UpdateOrientation : START ----------", this);
270
271         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
272         if (!pEcoreEvas)
273         {
274                 return;
275         }
276
277         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
278         if (!pImpl)
279         {
280                 return;
281         }
282
283         _Window* pRootWindow = pImpl->GetCore().GetRootWindow();
284         if (!pRootWindow)
285         {
286                 return;
287         }
288
289         int rotation = pEcoreEvas->GetWindowRotation(*pRootWindow);
290         OrientationStatus status = ORIENTATION_STATUS_NONE;
291         switch (rotation)
292         {
293         case 0:
294                 status = ORIENTATION_STATUS_PORTRAIT;
295                 break;
296         case 270:
297                 status = ORIENTATION_STATUS_LANDSCAPE;
298                 break;
299         case 180:
300                 status = ORIENTATION_STATUS_PORTRAIT_REVERSE;
301                 break;
302         case 90:
303                 status = ORIENTATION_STATUS_LANDSCAPE_REVERSE;
304                 break;
305         default:
306                 break;
307         }
308
309         if (__updateStatus == true)
310         {
311                 __statusChanged = false;
312                 if (__status != status)
313                 {
314                         __statusChanged = true;
315                         __updateStatus = false;
316                 }
317         }
318
319         __status = status;
320
321         pEcoreEvas->AllowSetWindowBounds(false);
322         FireEvent(status, true);
323         pEcoreEvas->AllowSetWindowBounds(true);
324
325         // For the form to be made by Ui-Builder
326         if ((__draw == true) && (__statusChanged == true))
327         {
328                 _ControlOrientation coreOrientation =
329                         (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
330                         _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
331
332                 Rectangle temp;
333                 bool exist = pImpl->GetBuilderBounds(coreOrientation, temp);
334                 if (exist)
335                 {
336                         pImpl->Invalidate(true);
337                 }
338         }
339
340         pEcoreEvas->RotateWindow(*pRootWindow, rotation, false);
341
342         if (__statusChanged == true)
343         {
344                 _TouchManager* pTouchManager = _TouchManager::GetInstance();
345                 if (pTouchManager)
346                 {
347                         pTouchManager->SetTouchCanceled(null);
348                 }
349         }
350
351         pImpl->Invalidate(true);
352
353         Rectangle bounds = pRootWindow->GetBounds();
354         SysLog(NID_UI, "[WM ROTATION][AGENT 0x%x][WIN 0x%x, ROT %d, %d, %d, %d, %d] Update Orientation.", this, pRootWindow->GetNativeHandle(), rotation, bounds.x, bounds.y, bounds.width, bounds.height);
355
356         SysLog(NID_UI, "[WM ROTATION][AGENT 0x%x] ---------- UpdateOrientation : END ----------", this);
357 }
358
359 void
360 _OrientationAgent::RequestOrientationEvent(void)
361 {
362         ClearLastResult();
363
364         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
365         SysTryReturnVoidResult(NID_UI, pImpl, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
366
367         unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
368         SysTryReturnVoidResult(NID_UI, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
369         pEventArgs->Construct();
370
371         unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(_REQUEST_ORIENTATION_EVENT));
372         SysTryReturnVoidResult(NID_UI, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
373
374         pEventArgs->Add(*(pString.get()));
375
376         _UiNotificationEvent event(pImpl->GetCore().GetHandle(), pEventArgs.get());
377
378         result r = _UiEventManager::GetInstance()->PostEvent(event);
379         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
380
381         pString.release();
382         pEventArgs.release();
383 }
384
385 void
386 _OrientationAgent::FireOrientationEvent(void)
387 {
388         if (__firePublicEvent)
389         {
390                 return;
391         }
392
393         __firePublicEvent = true;
394
395         SysLog(NID_UI, "Fire the orientation event.");
396
397         if (__statusChanged)
398         {
399                 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), __status);
400                 __pPublicEvent->Fire(*pArg);
401
402                 __updateStatus = true;
403         }
404 }
405
406 void
407 _OrientationAgent::FireEvent(OrientationStatus status, bool callback)
408 {
409         ClearLastResult();
410
411         _ControlManager* pCoreManager = _ControlManager::GetInstance();
412         SysAssert(pCoreManager);
413
414         _ControlImpl* pImpl = _ControlImpl::GetInstance(__publicControl);
415         if (!pImpl)
416         {
417                 return;
418         }
419
420         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
421         if (!pEcoreEvas)
422         {
423                 return;
424         }
425
426         _ControlOrientation coreOrientation =
427                 (status == ORIENTATION_STATUS_PORTRAIT || status == ORIENTATION_STATUS_PORTRAIT_REVERSE) ?
428                 _CONTROL_ORIENTATION_PORTRAIT : _CONTROL_ORIENTATION_LANDSCAPE;
429
430         _ControlImplManager* pImplManager = _ControlImplManager::GetInstance();
431         SysAssert(pImplManager);
432
433         // Core
434         pCoreManager->SetOrientation(coreOrientation);
435         pImplManager->SetOrientationStatus(status);
436         pImpl->GetCore().ChangeLayout(coreOrientation);
437
438         int owneeCount = pImpl->GetCore().GetOwneeCount();
439         for (int i = 0; i < owneeCount; i++)
440         {
441                 _Window* pOwnee = pImpl->GetCore().GetOwnee(i);
442                 if (pOwnee)
443                 {
444                         if (pOwnee->GetWindowType() == _WINDOW_TYPE_VE)
445                         {
446                                 pOwnee->ChangeLayout(coreOrientation);
447                         }
448                         else
449                         {
450                                 if (!((callback == true) && (pOwnee->IsRotationSynchronized() == true)))
451                                 {
452                                         pOwnee->ChangeLayout(coreOrientation);
453                                 }
454
455                                 if (pOwnee->GetVisibleState() == true)
456                                 {
457                                         pEcoreEvas->SetOwner(*pOwnee, pImpl->GetCore());
458                                 }
459                         }
460                 }
461         }
462
463         _Control* pParent = pImpl->GetCore().GetParent();
464         if (pParent)
465         {
466                 int owneeCount = pParent->GetOwneeCount();
467                 for (int i = 0; i < owneeCount; i++)
468                 {
469                         _Window* pOwnee = pParent->GetOwnee(i);
470                         if (pOwnee)
471                         {
472                                 if (pOwnee->GetWindowType() == _WINDOW_TYPE_VE)
473                                 {
474                                         pOwnee->ChangeLayout(coreOrientation);
475                                 }
476                                 else
477                                 {
478                                         if (!((callback == true) && (pOwnee->IsRotationSynchronized() == true)))
479                                         {
480                                                 pOwnee->ChangeLayout(coreOrientation);
481                                         }
482
483                                         if (pOwnee->GetVisibleState() == true)
484                                         {
485                                                 pEcoreEvas->SetOwner(*pOwnee, *pParent);
486                                         }
487                                 }
488                         }
489                 }
490         }
491
492         // Public
493         if (__firePublicEvent && __statusChanged)
494         {
495                 IEventArg* pArg = _PublicOrientationEvent::CreateOrientationEventArgN(*__pPublicEvent->GetSource(), status);
496                 __pPublicEvent->Fire(*pArg);
497
498                 __updateStatus = true;
499         }
500 }
501
502 void
503 _OrientationAgent::SetRotation(const _Window& window, Orientation orientation)
504 {
505         _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
506         if (!pEcoreEvas)
507         {
508                 return;
509         }
510
511         switch (orientation)
512         {
513         case ORIENTATION_PORTRAIT:
514                 pEcoreEvas->SetWindowPreferredRotation(window, 0);
515                 break;
516         case ORIENTATION_LANDSCAPE:
517                 pEcoreEvas->SetWindowPreferredRotation(window, 270);
518                 break;
519         case ORIENTATION_PORTRAIT_REVERSE:
520                 pEcoreEvas->SetWindowPreferredRotation(window, 180);
521                 break;
522         case ORIENTATION_LANDSCAPE_REVERSE:
523                 pEcoreEvas->SetWindowPreferredRotation(window, 90);
524                 break;
525         case ORIENTATION_AUTOMATIC:
526                 {
527                         pEcoreEvas->SetWindowPreferredRotation(window, -1);
528                         int autoRotation[3] = {0, 90, 270};
529                         pEcoreEvas->SetWindowAvailabledRotation(window, autoRotation, 3);
530                 }
531
532                 break;
533         case ORIENTATION_AUTOMATIC_FOUR_DIRECTION:
534                 {
535                         pEcoreEvas->SetWindowPreferredRotation(window, -1);
536                         int autoFourRotation[4] = {0, 90, 180, 270};
537                         pEcoreEvas->SetWindowAvailabledRotation(window, autoFourRotation, 4);
538                 }
539
540                 break;
541         default:
542                 break;
543         }
544 }
545
546 }} // Tizen::Ui