modify license, permission and remove ^M char
[platform/framework/native/uifw.git] / src / ui / FUi_ContainerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0/
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_ContainerImpl.cpp
20  * @brief               This is the implementation file for _ContainerImpl class.
21  */
22
23 #include <FUiLayout.h>
24 #include <FBaseSysLog.h>
25 #include <FApp_AppInfo.h>
26 #include "FUi_ContainerImpl.h"
27 #include "FUi_WindowImpl.h"
28 #include "FUi_Control.h"
29 #include "FUi_CoordinateSystemUtils.h"
30 #include "FUi_LayoutImpl.h"
31
32 using namespace Tizen::App;
33 using namespace Tizen::Base;
34 using namespace Tizen::Base::Collection;
35 using namespace Tizen::Graphics;
36
37 namespace Tizen { namespace Ui {
38
39 _ContainerImpl*
40 _ContainerImpl::CreateContainerImplN(Container* pPublic)
41 {
42         ClearLastResult();
43
44         _Control* pCore = _Control::CreateControlN();
45         result r = GetLastResult();
46         SysTryReturn(NID_UI, pCore, null, r, "[%s] Propagating.", GetErrorMessage(r));
47
48         _ContainerImpl* pImpl = new (std::nothrow) _ContainerImpl(pPublic, pCore);
49         r = CheckConstruction(pCore, pImpl);
50         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
51
52         return pImpl;
53 }
54
55 _ContainerImpl*
56 _ContainerImpl::CreateContainerImplN(Container* pPublic, const Rectangle& bounds,
57                                                                                 const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout,
58                                                                                 bool resizable, bool movable)
59 {
60         result r = E_SUCCESS;
61
62         _Control* pCore = _Control::CreateControlN();
63         SysTryReturn(NID_UI, pCore, null, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(r));
64
65         _ContainerImpl* pImpl =
66                 new (std::nothrow) _ContainerImpl(pPublic, pCore, bounds,
67                                                                                                   pPublicPortraitLayout, pPublicLandscapeLayout,
68                                                                                                   resizable, movable);
69         r = CheckConstruction(pCore, pImpl);
70         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
71
72         ClearLastResult();
73
74         return pImpl;
75 }
76
77 _ContainerImpl*
78 _ContainerImpl::CreateContainerImplN(Container* pPublic, const FloatRectangle& bounds,
79                                                                                 const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout,
80                                                                                 bool resizable, bool movable)
81 {
82         result r = E_SUCCESS;
83
84         _Control* pCore = _Control::CreateControlN();
85         SysTryReturn(NID_UI, pCore, null, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(r));
86
87         _ContainerImpl* pImpl =
88                 new (std::nothrow) _ContainerImpl(pPublic, pCore, bounds,
89                                                                                                   pPublicPortraitLayout, pPublicLandscapeLayout,
90                                                                                                   resizable, movable);
91         r = CheckConstruction(pCore, pImpl);
92         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
93
94         ClearLastResult();
95
96         return pImpl;
97 }
98
99 _ContainerImpl*
100 _ContainerImpl::GetInstance(Container& container)
101 {
102         return static_cast <_ContainerImpl*> (container._pControlImpl);
103 }
104
105 const _ContainerImpl*
106 _ContainerImpl::GetInstance(const Container& container)
107 {
108         return static_cast <const _ContainerImpl*> (container._pControlImpl);
109 }
110
111 _ContainerImpl::~_ContainerImpl(void)
112 {
113         if (!HasCore())
114         {
115                 return;
116         }
117
118         RemoveAllChildren(true);
119 }
120
121 const char*
122 _ContainerImpl::GetPublicClassName(void) const
123 {
124         return "Tizen::Ui::Container";
125 }
126
127 const Container&
128 _ContainerImpl::GetPublic(void) const
129 {
130         return static_cast <const Container&>(_ControlImpl::GetPublic());
131 }
132
133 Container&
134 _ContainerImpl::GetPublic(void)
135 {
136         return static_cast <Container&>(_ControlImpl::GetPublic());
137 }
138
139 // E_INVALID_ARG, E_OUT_OF_MEMORY
140 result
141 _ContainerImpl::AddChild(_ControlImpl* pChild, bool transferOwnership)
142 {
143         ClearLastResult();
144         result r = E_SUCCESS;
145
146         SysTryReturn(NID_UI,
147                                 pChild != null, E_INVALID_ARG,
148                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
149
150         SysTryReturn(NID_UI,
151                                 IsChildAttachable(*pChild), E_INVALID_ARG,
152                                 E_INVALID_ARG, "[E_INVALID_ARG] %s cannot be a child of %s.",
153                                 pChild->GetPublicClassName(), GetPublicClassName());
154
155         _ContainerImpl* pOldParent = pChild->GetParent();
156
157         SysTryReturn(NID_UI,
158                                 (pOldParent != this), E_INVALID_ARG,
159                                 E_INVALID_ARG, "[E_INVALID_ARG] The child control is already attached to this container.");
160
161         SysTryReturn(NID_UI,
162                                 pOldParent == null, E_INVALID_ARG,
163                                 E_INVALID_ARG, "[E_INVALID_ARG] Unable to add the child which already has another parent.");
164
165         r = __controlPublics.Add(pChild->GetPublic());
166         if (IsFailed(r))
167         {
168                 SysAssert(r == E_OUT_OF_MEMORY); // I can't beleve Tizen::Base.
169                 SysLogException(NID_UI, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
170                 return E_OUT_OF_MEMORY;
171         }
172
173         r = GetCore().AttachChild(pChild->GetCore());
174         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] propagated.", GetErrorMessage(r));
175
176         return E_SUCCESS;
177 }
178
179 result
180 _ContainerImpl::Destroy(void)
181 {
182         result r = E_SUCCESS;
183
184         _ContainerImpl* pParent = GetParent();
185         if (pParent)
186         {
187                 r = pParent->RemoveChild(this, false);
188         }
189         else
190         {
191                 _Control* pParent = GetCore().GetParent();
192                 if (pParent)
193                 {
194                         ControlList& children = pParent->GetChildList();
195                         r = children.Remove(&GetCore());
196                 }
197         }
198         RemoveAllChildren(true);
199         Container* pContainer = &GetPublic();
200         delete pContainer;
201         pContainer = null;
202
203         return r;
204 }
205
206 result
207 _ContainerImpl::RemoveControl(_ControlImpl* pChild, bool deallocate)
208 {
209         ClearLastResult();
210         result r = E_SUCCESS;
211
212         _ContainerImpl* pChildContainer = dynamic_cast <_ContainerImpl*>(pChild);
213         if (pChildContainer)
214         {
215                 _ContainerImpl* pParent = pChildContainer->GetParent();
216                 SysTryReturn(NID_UI, pParent, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The control is not a child of this container.");
217
218                 r = pParent->RemoveChild(pChildContainer, false);
219                 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
220                 pChildContainer->RemoveAllChildren(true);
221                 r = GetLastResult();
222                 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
223                 if (deallocate)
224                 {
225                         Container* pContainer = &pChildContainer->GetPublic();
226                         delete pContainer;
227                         pContainer = null;
228                 }
229         }
230         else
231         {
232                 SysTryReturn(NID_UI, pChild, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
233                 r = RemoveChild(pChild, deallocate);
234                 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
235         }
236
237         return r;
238 }
239
240 result
241 _ContainerImpl::RemoveChild(_ControlImpl* pChild, bool deallocate)
242 {
243         ClearLastResult();
244         result r = E_SUCCESS;
245
246         SysTryReturn(NID_UI,
247                                 pChild != null, E_INVALID_ARG,
248                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
249
250         if (pChild->GetCore().GetArea() == _CONTROL_AREA_SYSTEM)
251         {
252                 return E_SUCCESS;
253         }
254
255         GetChildIndex(pChild);
256         r = GetLastResult();
257         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
258
259         r = GetCore().DetachChild(pChild->GetCore());
260         SysAssert(r == E_SUCCESS);
261
262         r = __controlPublics.Remove(pChild->GetPublic(), deallocate);
263         SysAssert(r == E_SUCCESS);
264
265         return E_SUCCESS;
266 }
267
268 result
269 _ContainerImpl::RemoveControl(int index)
270 {
271         ClearLastResult();
272         result r = E_SUCCESS;
273
274         _ControlImpl* pChild = GetChild(index); // Find child control.
275         r = GetLastResult();
276         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
277
278         _ContainerImpl* pChildContainer = dynamic_cast <_ContainerImpl*>(pChild);
279         if (pChildContainer)
280         {
281                 _ContainerImpl* pParent = pChildContainer->GetParent();
282                 if (pParent)
283                 {
284                         r = pParent->RemoveChild(pChildContainer, false);
285                         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
286                 }
287                 pChildContainer->RemoveAllChildren(true);
288                 r = GetLastResult();
289                 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
290                 Container* pContainer = &pChildContainer->GetPublic();
291                 delete pContainer;
292                 pContainer = null;
293         }
294         else
295         {
296                 r = RemoveChild(index);
297                 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
298         }
299
300         return r;
301 }
302
303 result
304 _ContainerImpl::RemoveChild(int index)
305 {
306         ClearLastResult();
307         result r = E_SUCCESS;
308
309         _ControlImpl* pChild = GetChild(index); // Find child control.
310         r = GetLastResult();
311         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
312
313         SysAssert(pChild);
314         SysTryReturn(NID_UI, pChild, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The child to remove is null.");
315
316         GetCore().DetachChild(pChild->GetCore());
317         SysAssert(GetLastResult() == E_SUCCESS);
318
319         r = __controlPublics.Remove(pChild->GetPublic(), true);
320         SysAssert(r == E_SUCCESS);
321
322         return E_SUCCESS;
323 }
324
325 void
326 _ContainerImpl::DeleteAllChildren(_ContainerImpl* pChild, bool detachSystemChild, ArrayList* pChildrenList)
327 {
328         ArrayList* pList = static_cast <ArrayList*>(pChild->GetChildrenPublic());
329         int count = pList->GetCount();
330         for (int index = count - 1; index >= 0; index--)
331         {
332                 Control* pControl = static_cast <Control*>(pList->GetAt(index));
333                 if (pControl)
334                 {
335                         Container* pContainer = dynamic_cast <Container*>(pControl);
336                         result r = GetLastResult();
337                         if (IsFailed(r))
338                         {
339                                 SysAssert(r == E_OUT_OF_RANGE);
340                                 SysLogException(NID_UI,
341                                                  E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The specified index is out of range (index = %d, count = %d.)",
342                                                  index, GetChildCount());
343                                 return;
344                         }
345
346                         if (pContainer)
347                         {
348                                 _ContainerImpl* pContainerImpl = _ContainerImpl::GetInstance(*pContainer);
349                                 ArrayList* pContainerChildrenList = static_cast <ArrayList*>(pContainerImpl->GetChildrenPublic());
350                                 int childrenCount = pContainerChildrenList->GetCount();
351
352                                 if (childrenCount > 0)
353                                 {
354                                         DeleteAllChildren(pContainerImpl, detachSystemChild, pContainerChildrenList);
355                                 }
356                                 r = pChildrenList->Remove(*pContainer, true);
357                                 SysAssert(r == E_SUCCESS);
358                         }
359                         else
360                         {
361                                 _ControlImpl* pControlImpl = _ControlImpl::GetInstance(*pControl);
362                                 if (pControlImpl)
363                                 {
364                                         if (detachSystemChild || pControlImpl->GetCore().GetArea() != _CONTROL_AREA_SYSTEM)
365                                         {
366                                                 r = pChildrenList->Remove(*pControl, true);
367                                                 SysAssert(r == E_SUCCESS);
368                                         }
369                                 }
370                         }
371                 }
372         }
373 }
374
375 void
376 _ContainerImpl::RemoveAllChildren(bool detachSystemChild, bool callOnDetachingFromMaintree)
377 {
378         if (callOnDetachingFromMaintree && !GetCore().IsPostOrderTraversal())
379         {
380                 GetCore().GetControlDelegate().OnDetachingFromMainTree();
381         }
382         GetCore().DetachAllChildren(detachSystemChild, true);
383         SysAssert(GetLastResult() == E_SUCCESS);
384         if (callOnDetachingFromMaintree && GetCore().IsPostOrderTraversal())
385         {
386                 GetCore().GetControlDelegate().OnDetachingFromMainTree();
387         }
388         ArrayList* pChildrenList = static_cast <ArrayList*>(GetChildrenPublic());
389         DeleteAllChildren(this, detachSystemChild, pChildrenList);
390 }
391
392 result
393 _ContainerImpl::MoveChildToTop(const _ControlImpl& child)
394 {
395         ClearLastResult();
396         result r = E_SUCCESS;
397
398         SysTryReturn(NID_UI,
399                                 child.GetParent() == this, E_INVALID_ARG,
400                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my child.");
401
402         r = GetCore().MoveChildToTop(child.GetCore());
403         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
404
405         r = __controlPublics.Remove(child.GetPublic());
406         SysAssert(r == E_SUCCESS);
407
408         r = __controlPublics.Add(child.GetPublic());
409         SysAssert(r == E_SUCCESS);
410
411         return E_SUCCESS;
412 }
413
414 result
415 _ContainerImpl::MoveChildBefore(const _ControlImpl& targetChild, const _ControlImpl& child)
416 {
417         ClearLastResult();
418         result r = E_SUCCESS;
419         int index = -1;
420
421         SysTryReturn(NID_UI,
422                                 targetChild.GetParent() == this, E_INVALID_ARG,
423                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my targetChild.");
424
425         SysTryReturn(NID_UI,
426                                 child.GetParent() == this, E_INVALID_ARG,
427                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my child.");
428
429         r = GetCore().MoveChildBefore(targetChild.GetCore(), child.GetCore());
430         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
431
432         r = __controlPublics.Remove(child.GetPublic());
433         SysAssert(r == E_SUCCESS);
434
435         r = __controlPublics.IndexOf(targetChild.GetPublic(), index);
436         SysAssert(r == E_SUCCESS);
437
438         r = __controlPublics.InsertAt(child.GetPublic(), index);
439         SysAssert(r == E_SUCCESS);
440
441         return E_SUCCESS;
442 }
443
444 Tizen::Base::Collection::IList*
445 _ContainerImpl::GetChildrenPublic(void) const
446 {
447         ClearLastResult();
448         return const_cast <LinkedList*>(&__controlPublics);
449 }
450
451 // E_OUT_OF_RANGE
452 _ControlImpl*
453 _ContainerImpl::GetChild(int index) const
454 {
455         ClearLastResult();
456
457         const Control* pControl = static_cast <const Control*>(__controlPublics.GetAt(index));
458         result r = GetLastResult();
459         if (IsFailed(r))
460         {
461                 SysAssert(r == E_OUT_OF_RANGE); // I can't beleve Tizen::Base.
462                 SysLogException(NID_UI,
463                                  E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The specified index is out of range (index = %d, count = %d.)",
464                                  index, GetChildCount());
465
466                 return null;
467         }
468
469         SysAssert(pControl);
470
471         return const_cast <_ControlImpl*>(_ControlImpl::GetInstance(*pControl));
472 }
473
474 _ControlImpl*
475 _ContainerImpl::SearchControlByName(const Tizen::Base::String& name, bool recursive, bool searchMyself) const
476 {
477         ClearLastResult();
478
479         if (searchMyself == true || (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat()))
480         {
481                 if (name.CompareTo(GetName()) == 0)
482                 {
483                         return const_cast <_ContainerImpl*>(this);
484                 }
485         }
486
487         _ControlImpl* pChildFound = null;
488         for (int i = 0; i < __controlPublics.GetCount(); ++i)
489         {
490                 _ControlImpl* pChild = GetChild(i);
491
492                 SysAssert(pChild);
493                 if (pChild == null)
494                 {
495                         continue;
496                 }
497
498                 _ContainerImpl* pChildAsContainer = dynamic_cast <_ContainerImpl*>(pChild);
499                 if (pChildAsContainer && recursive)
500                 {
501                         pChildFound = pChildAsContainer->SearchControlByName(name, true, true);
502                         if (pChildFound != null)
503                         {
504                                 break;
505                         }
506                 }
507                 else if (name.CompareTo(pChild->GetName()) == 0)
508                 {
509                         pChildFound = pChild;
510                         break;
511                 }
512         }
513
514         return pChildFound;
515 }
516
517 // [ToDo] Check if the public Container leaves the out-param index as it is.
518 int
519 _ContainerImpl::GetChildIndex(const _ControlImpl* pChild) const
520 {
521         int index = -1;
522
523         result r = __controlPublics.IndexOf(pChild->GetPublic(), index);
524         if (IsFailed(r))
525         {
526                 SysAssert(r == E_OBJ_NOT_FOUND);
527                 SysLogException(NID_UI, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The control is not a child of this container.");
528                 return -1;
529         }
530
531         return index;
532 }
533
534 int
535 _ContainerImpl::GetChildCount(void) const
536 {
537         ClearLastResult();
538         return __controlPublics.GetCount();
539 }
540
541 Layout*
542 _ContainerImpl::GetPublicPortraitLayoutN(void) const
543 {
544         ClearLastResult();
545
546         Layout* pLayout = _LayoutImpl::CreatePublicLayoutN(__portraitLayout);
547         result r = GetLastResult();
548         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
549
550         return pLayout;
551 }
552
553 Layout*
554 _ContainerImpl::GetPublicLandscapeLayoutN(void) const
555 {
556         ClearLastResult();
557
558         Layout* pLayout = _LayoutImpl::CreatePublicLayoutN(__landscapeLayout);
559         result r = GetLastResult();
560         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
561
562         return pLayout;
563 }
564
565 Layout*
566 _ContainerImpl::GetPublicLayoutN(void) const
567 {
568         return (GetCore().GetOrientation() == _CONTROL_ORIENTATION_LANDSCAPE) ?
569                    GetPublicLandscapeLayoutN() : GetPublicPortraitLayoutN();
570 }
571
572 result
573 _ContainerImpl::SetChildAt(const _ControlImpl* pChild, int index)
574 {
575         ClearLastResult();
576         result r = E_SUCCESS;
577
578         SysTryReturn(NID_UI,
579                                 pChild, E_INVALID_ARG,
580                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
581
582         // In API 2.0, (0 <= index) was not checked but checked at the ArrayList::SetAt().
583         // So, I check the case here. No problem.
584         SysTryReturn(NID_UI,
585                                 (0 <= index && index < GetCore().GetChildCount()), E_OUT_OF_RANGE,
586                                 E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The specified index is out of range (index = %d, count = %d)",
587                                 index, GetCore().GetChildCount());
588
589         // [ToDo] 2.0 bug: The error should be E_INVALID_ARG.
590         // And I think this must be checked before the range check.
591         _ContainerImpl* pParent = pChild->GetParent();
592         SysTryReturn(NID_UI,
593                                 pParent == this, E_SYSTEM,
594                                 E_SYSTEM, "[E_SYSTEM] The container is not the parent of the specified control.");
595
596         int oldIndex = GetCore().GetChildIndex(pChild->GetCore());
597         SysAssert(GetLastResult() == E_SUCCESS);
598
599         if (index == oldIndex)
600         {
601                 return E_SUCCESS;
602         }
603
604         r = __controlPublics.SetAt(pChild->GetPublic(), index);
605         SysAssert(r == E_SUCCESS);
606
607         _Control* pTargetChild = GetCore().GetChild(index);
608         SysAssert(pTargetChild);
609
610         r = GetCore().MoveChildBefore(*pTargetChild, pChild->GetCore());
611         SysAssert(r == E_SUCCESS);
612
613         return E_SUCCESS;
614 }
615
616 bool
617 _ContainerImpl::IsAncestorOf(const _ControlImpl* pChild) const
618 {
619         SysTryReturn(NID_UI, pChild, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
620         return GetCore().IsAncestorOf(pChild->GetCore());
621 }
622
623 void
624 _ContainerImpl::OnDraw(void)
625 {
626         GetPublic().OnClearBackground();
627
628         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
629         {
630                 GetCore().OnDraw();
631         }
632
633         GetPublic().OnDraw();
634 }
635
636 void
637 _ContainerImpl::OnChangeLayout(_ControlOrientation orientation)
638 {
639         result r = E_SUCCESS;
640         _ControlImpl::OnChangeLayout(orientation);
641
642         if (orientation == _CONTROL_ORIENTATION_PORTRAIT && !__portraitLayout.IsNull())
643         {
644                 r = GetCore().SetCurrentLayout(__portraitLayout->GetCore());
645                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout as portrait");
646         }
647         else if (orientation == _CONTROL_ORIENTATION_LANDSCAPE && !__landscapeLayout.IsNull())
648         {
649                 r = GetCore().SetCurrentLayout(__landscapeLayout->GetCore());
650                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout as landscape.");
651         }
652 }
653
654 void
655 _ContainerImpl::OnVisibleStateChanging(void)
656 {
657         GetPublic().OnShowStateChanging(GetVisibleState());
658         _ControlImpl::OnVisibleStateChanging();
659 }
660
661 void
662 _ContainerImpl::OnVisibleStateChanged(void)
663 {
664         _ControlImpl::OnVisibleStateChanged();
665         GetPublic().OnShowStateChanged(GetVisibleState());
666 }
667
668 result
669 _ContainerImpl::OnBoundsChanging(const Rectangle& bounds)
670 {
671         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
672         if (pChild)
673         {
674                 GetPublic().OnBoundsChanging(_CoordinateSystemUtils::ConvertToInteger(__oldBounds), bounds);
675         }
676
677         return _ControlImpl::OnBoundsChanging(bounds);
678 }
679
680 result
681 _ContainerImpl::OnBoundsChanging(const FloatRectangle& bounds)
682 {
683         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
684         if (pChild)
685         {
686                 GetPublic().OnBoundsChanging(__oldBounds, bounds);
687         }
688         return _ControlImpl::OnBoundsChanging(bounds);
689 }
690
691 void
692 _ContainerImpl::OnBoundsChanged(void)
693 {
694         _ControlImpl::OnBoundsChanged();
695         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
696         if (pChild)
697         {
698                 GetPublic().OnBoundsChanged(_CoordinateSystemUtils::ConvertToInteger(__oldBounds), GetBounds());
699                 GetPublic().OnBoundsChanged(__oldBounds, GetBoundsF());
700         }
701 }
702
703 void
704 _ContainerImpl::OnEvaluateSize(Dimension& evaluatedSize)
705 {
706         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
707         if (pChild)
708         {
709                 GetPublic().OnEvaluateSize(evaluatedSize);
710         }
711         _ControlImpl::OnEvaluateSize(evaluatedSize);
712 }
713
714 bool
715 _ContainerImpl::OnEvaluateSize(FloatDimension& evaluatedSize)
716 {
717         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
718         bool changed = false;
719         if (pChild)
720         {
721                 changed = GetPublic().OnEvaluateSize(evaluatedSize);
722         }
723         _ControlImpl::OnEvaluateSize(evaluatedSize);
724         return changed;
725 }
726
727 void
728 _ContainerImpl::CallOnDraw(void)
729 {
730         if (!_AppInfo::IsOspCompat())
731         {
732                 GetCore().OnDraw();
733         }
734 }
735
736 void
737 _ContainerImpl::Initialize(Control* pPublic, _Control* pCore, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout)
738 {
739         result r = GetLastResult();
740         if (IsFailed(r))
741         {
742                 return;
743         }
744
745         _SharedPtr <Tizen::Ui::_LayoutImpl> spPortraitLayout;
746         _SharedPtr <Tizen::Ui::_LayoutImpl> spLandscapeLayout;
747
748         // Check if all or none
749         SysAssert(
750                 (pPublicPortraitLayout && pPublicLandscapeLayout) ||
751                 (!pPublicPortraitLayout && !pPublicLandscapeLayout)
752                 );
753
754         if (pPublicPortraitLayout)
755         {
756                 r = SetLayout(*pCore, _CONTROL_ORIENTATION_PORTRAIT, pPublicPortraitLayout);
757                 if (IsFailed(r))
758                 {
759                         return;
760                 }
761
762                 r = pCore->SetCurrentLayout(__portraitLayout->GetCore());
763                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout.");
764         }
765
766         if (pPublicLandscapeLayout)
767         {
768                 r = SetLayout(*pCore, _CONTROL_ORIENTATION_LANDSCAPE, pPublicLandscapeLayout);
769                 if (IsFailed(r))
770                 {
771                         return;
772                 }
773         }
774 }
775
776 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout)
777         : _ControlImpl(pPublic, pCore)
778 {
779         Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
780 }
781
782 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const Rectangle& bounds, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout, bool resizable, bool movable)
783         : _ControlImpl(pPublic, pCore)
784 {
785         result r = E_SUCCESS;
786
787         Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
788
789         r = GetLastResult();
790         if (IsFailed(r))
791         {
792                 return;
793         }
794
795         bool allOrNone = (pPublicPortraitLayout && pPublicLandscapeLayout) || (!pPublicPortraitLayout && !pPublicLandscapeLayout);
796         SysAssert(allOrNone);
797
798         r = SetBounds(bounds);
799         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
800
801         pCore->SetResizable(resizable);
802         pCore->SetMovable(movable);
803 }
804
805 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const FloatRectangle& bounds, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout, bool resizable, bool movable)
806         : _ControlImpl(pPublic, pCore)
807 {
808         result r = E_SUCCESS;
809
810         Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
811
812         r = GetLastResult();
813         if (IsFailed(r))
814         {
815                 return;
816         }
817
818         bool allOrNone = (pPublicPortraitLayout && pPublicLandscapeLayout) || (!pPublicPortraitLayout && !pPublicLandscapeLayout);
819         SysAssert(allOrNone);
820
821         r = SetBounds(bounds);
822         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
823
824         pCore->SetResizable(resizable);
825         pCore->SetMovable(movable);
826 }
827
828 result
829 _ContainerImpl::SetLayout(_Control& core, _ControlOrientation orientation, const Layout* pPublicLayout)
830 {
831         SysAssert(pPublicLayout);
832
833         result r = E_SUCCESS;
834
835         const char* orientationStatus = (orientation == _CONTROL_ORIENTATION_PORTRAIT) ?
836                                                                  "portrait" : "landscape";
837
838         _SharedPtr <Tizen::Ui::_LayoutImpl>& spLayout = (orientation == _CONTROL_ORIENTATION_PORTRAIT) ?
839                                                                  __portraitLayout : __landscapeLayout;
840
841         spLayout = _LayoutImpl::GetLayoutImpl(const_cast <Layout*>(pPublicLayout));
842         SysTryReturn(NID_UI,
843                                 !spLayout.IsNull(), E_INVALID_ARG,
844                                 E_INVALID_ARG, "[E_INVALID_ARG] The %s layout is invalid object", orientationStatus);
845
846         r = core.AddLayout(spLayout->GetCore());
847         if (IsFailed(r))
848         {
849                 switch (r)
850                 {
851                 case E_INVALID_ARG:
852                         SysLogException(NID_UI, E_INVALID_ARG, "[E_INVALID_ARG] The %s layout is already used.", orientationStatus);
853                         break;
854                 default:
855                         SysLogException(NID_UI, E_SYSTEM, "[E_SYSTEM] Failed to add the %s layout.", orientationStatus);
856                 }
857
858                 return r;
859         }
860
861         return E_SUCCESS;
862 }
863
864 bool
865 _ContainerImpl::IsChildAttachable(_ControlImpl& child) const
866 {
867         if (dynamic_cast <_WindowImpl*>(&child) != null)
868         {
869                 return false;
870         }
871
872         return true;
873 }
874
875
876 result
877 _ContainerImpl::SetControlAlwaysOnTop(Control& control, bool alwaysOnTop)
878 {
879         _ControlImpl* pChild = _ControlImpl::GetInstance(control);
880         SysTryReturn(NID_UI,
881                                 pChild, E_INVALID_ARG,
882                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
883
884         _Control& childCore = pChild->GetCore();
885         const bool atBottom = childCore.GetLayer() == _CONTROL_LAYER_CLIENT_BOTTOM;
886
887         if (atBottom && !alwaysOnTop)
888         {
889                 SysLogException(NID_UI, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The bottom child cannot be reset.");
890                 return E_INVALID_OPERATION;
891         }
892
893         return alwaysOnTop ?
894                    GetCore().SetChildAlwaysOnTop(childCore) :
895                    GetCore().ResetChildLayer(childCore);
896 }
897
898 result
899 _ContainerImpl::SetControlAlwaysAtBottom(Control& control, bool alwaysAtBottom)
900 {
901         _ControlImpl* pChild = _ControlImpl::GetInstance(control);
902         SysTryReturn(NID_UI,
903                                 pChild, E_INVALID_ARG,
904                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
905
906         _Control& childCore = pChild->GetCore();
907         const bool onTop = childCore.GetLayer() == _CONTROL_LAYER_CLIENT_TOP;
908
909         if (onTop && !alwaysAtBottom)
910         {
911                 SysLogException(NID_UI, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The top child cannot be reset.");
912                 return E_INVALID_OPERATION;
913         }
914
915         return alwaysAtBottom ?
916                    GetCore().SetChildAlwaysAtBottom(childCore) :
917                    GetCore().ResetChildLayer(childCore);
918 }
919
920 bool
921 _ContainerImpl::IsControlAlwaysAtBottom(const Control& control) const
922 {
923         const _ControlImpl* pChild = _ControlImpl::GetInstance(control);
924         SysTryReturn(NID_UI,
925                                 pChild, false,
926                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
927
928         SysTryReturn(NID_UI,
929                            pChild->GetParent() == this, false,
930                            E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not a child of this container.");
931
932         return pChild->GetCore().GetLayer() == _CONTROL_LAYER_CLIENT_BOTTOM;
933 }
934
935 bool
936 _ContainerImpl::IsControlAlwaysOnTop(const Control& control) const
937 {
938         const _ControlImpl* pChild = _ControlImpl::GetInstance(control);
939         SysTryReturn(NID_UI,
940                                 pChild, false,
941                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
942
943         SysTryReturn(NID_UI,
944                            pChild->GetParent() == this, false,
945                            E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not a child of this container.");
946
947         return pChild->GetCore().GetLayer() == _CONTROL_LAYER_CLIENT_TOP;
948 }
949
950 }} //Tizen::Ui