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