Tizen 2.1 base
[framework/osp/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 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  * @file                FUi_ContainerImpl.cpp
19  * @brief               This is the implementation file for _ContainerImpl class.
20  */
21
22 #include <FUiLayout.h>
23 #include <FBaseSysLog.h>
24 #include <FApp_AppInfo.h>
25 #include "FUi_ContainerImpl.h"
26 #include "FUi_WindowImpl.h"
27 #include "FUi_Control.h"
28 #include "FUi_LayoutImpl.h"
29
30 using namespace Tizen::App;
31 using namespace Tizen::Base;
32 using namespace Tizen::Base::Collection;
33 using namespace Tizen::Graphics;
34
35 namespace Tizen { namespace Ui {
36
37 _ContainerImpl*
38 _ContainerImpl::CreateContainerImplN(Container* pPublic)
39 {
40         ClearLastResult();
41
42         _Control* pCore = _Control::CreateControlN();
43         result r = GetLastResult();
44         SysTryReturn(NID_UI, pCore, null, r, "[%s] Propagating.", GetErrorMessage(r));
45
46         _ContainerImpl* pImpl = new (std::nothrow) _ContainerImpl(pPublic, pCore);
47         r = CheckConstruction(pCore, pImpl);
48         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
49
50         return pImpl;
51 }
52
53 _ContainerImpl*
54 _ContainerImpl::CreateContainerImplN(Container* pPublic, const Rectangle& bounds,
55                                                                                 const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout,
56                                                                                 bool resizable, bool movable)
57 {
58         result r = E_SUCCESS;
59
60         _Control* pCore = _Control::CreateControlN();
61         SysTryReturn(NID_UI, pCore, null, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(r));
62
63         _ContainerImpl* pImpl =
64                 new (std::nothrow) _ContainerImpl(pPublic, pCore, bounds,
65                                                                                                   pPublicPortraitLayout, pPublicLandscapeLayout,
66                                                                                                   resizable, movable);
67         r = CheckConstruction(pCore, pImpl);
68         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
69
70         ClearLastResult();
71
72         return pImpl;
73 }
74
75
76 _ContainerImpl*
77 _ContainerImpl::GetInstance(Container& container)
78 {
79         return static_cast <_ContainerImpl*> (container._pControlImpl);
80 }
81
82 const _ContainerImpl*
83 _ContainerImpl::GetInstance(const Container& container)
84 {
85         return static_cast <const _ContainerImpl*> (container._pControlImpl);
86 }
87
88 _ContainerImpl::~_ContainerImpl(void)
89 {
90         if (!HasCore())
91         {
92                 return;
93         }
94
95         RemoveAllChildren();
96 }
97
98 const char*
99 _ContainerImpl::GetPublicClassName(void) const
100 {
101         return "Tizen::Ui::Container";
102 }
103
104 const Container&
105 _ContainerImpl::GetPublic(void) const
106 {
107         return static_cast <const Container&>(_ControlImpl::GetPublic());
108 }
109
110 Container&
111 _ContainerImpl::GetPublic(void)
112 {
113         return static_cast <Container&>(_ControlImpl::GetPublic());
114 }
115
116 // E_INVALID_ARG, E_OUT_OF_MEMORY
117 result
118 _ContainerImpl::AddChild(_ControlImpl* pChild, bool transferOwnership)
119 {
120         ClearLastResult();
121         result r = E_SUCCESS;
122
123         SysTryReturn(NID_UI,
124                                 pChild != null, E_INVALID_ARG,
125                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
126
127         SysTryReturn(NID_UI,
128                                 IsChildAttachable(*pChild), E_INVALID_ARG,
129                                 E_INVALID_ARG, "[E_INVALID_ARG] %s cannot be a child of %s.",
130                                 pChild->GetPublicClassName(), GetPublicClassName());
131
132         _ContainerImpl* pOldParent = pChild->GetParent();
133
134         SysTryReturn(NID_UI,
135                                 (pOldParent != this), E_INVALID_ARG,
136                                 E_INVALID_ARG, "[E_INVALID_ARG] The child control is already attached to this container.");
137
138         SysTryReturn(NID_UI,
139                                 pOldParent == null, E_INVALID_ARG,
140                                 E_INVALID_ARG, "[E_INVALID_ARG] Unable to add the child which already has another parent.");
141
142         r = __controlPublics.Add(pChild->GetPublic());
143         if (IsFailed(r))
144         {
145                 SysAssert(r == E_OUT_OF_MEMORY); // I can't beleve Tizen::Base.
146                 SysLogException(NID_UI, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
147                 return E_OUT_OF_MEMORY;
148         }
149
150         r = GetCore().AttachChild(pChild->GetCore());
151         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] propagated.", GetErrorMessage(r));
152
153         return E_SUCCESS;
154 }
155
156 // E_INVALID_ARG, E_OBJ_NOT_FOUND
157 result
158 _ContainerImpl::RemoveChild(_ControlImpl* pChild, bool deallocate)
159 {
160         ClearLastResult();
161         result r = E_SUCCESS;
162
163         SysTryReturn(NID_UI,
164                                 pChild != null, E_INVALID_ARG,
165                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
166
167         if (pChild->GetCore().GetArea() == _CONTROL_AREA_SYSTEM)
168         {
169                 return E_SUCCESS;
170         }
171
172         GetChildIndex(pChild);
173         r = GetLastResult();
174         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
175
176         r = GetCore().DetachChild(pChild->GetCore());
177         SysAssert(r == E_SUCCESS);
178
179         r = __controlPublics.Remove(pChild->GetPublic(), deallocate);
180         SysAssert(r == E_SUCCESS);
181
182         return E_SUCCESS;
183 }
184
185 result
186 _ContainerImpl::RemoveChild(int index)
187 {
188         ClearLastResult();
189         result r = E_SUCCESS;
190
191         _ControlImpl* pChild = GetChild(index); // Find child control.
192         r = GetLastResult();
193         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
194
195         SysAssert(pChild);
196         SysTryReturn(NID_UI, pChild, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The child to remove is null.");
197
198         GetCore().DetachChild(pChild->GetCore());
199         SysAssert(GetLastResult() == E_SUCCESS);
200
201         r = __controlPublics.Remove(pChild->GetPublic(), true);
202         SysAssert(r == E_SUCCESS);
203
204         return E_SUCCESS;
205 }
206
207 void
208 _ContainerImpl::RemoveAllChildren(bool detachSystemChild)
209 {
210         ClearLastResult();
211         result r = E_SUCCESS;
212
213         GetCore().DetachAllChildren(detachSystemChild);
214         SysAssert(GetLastResult() == E_SUCCESS);
215
216         if (detachSystemChild)
217         {
218                 __controlPublics.RemoveAll(true);
219         }
220         else
221         {
222                 int childCount = __controlPublics.GetCount();
223                 int itemIndex = 0;
224
225                 while (childCount--)
226                 {
227                         _ControlImpl* pControl = GetChild(itemIndex);
228                         if (pControl->GetCore().GetArea() == _CONTROL_AREA_SYSTEM)
229                         {
230                                 itemIndex++;
231                                 continue;
232                         }
233
234                         r = __controlPublics.Remove(pControl->GetPublic(), true);
235                         SysAssert(r == E_SUCCESS);
236                 }
237         }
238 }
239
240 result
241 _ContainerImpl::MoveChildToTop(const _ControlImpl& child)
242 {
243         ClearLastResult();
244         result r = E_SUCCESS;
245
246         SysTryReturn(NID_UI,
247                                 child.GetParent() == this, E_INVALID_ARG,
248                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my child.");
249
250         r = GetCore().MoveChildToTop(child.GetCore());
251         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
252
253         r = __controlPublics.Remove(child.GetPublic());
254         SysAssert(r == E_SUCCESS);
255
256         r = __controlPublics.Add(child.GetPublic());
257         SysAssert(r == E_SUCCESS);
258
259         return E_SUCCESS;
260 }
261
262 result
263 _ContainerImpl::MoveChildBefore(const _ControlImpl& targetChild, const _ControlImpl& child)
264 {
265         ClearLastResult();
266         result r = E_SUCCESS;
267         int index = -1;
268
269         SysTryReturn(NID_UI,
270                                 targetChild.GetParent() == this, E_INVALID_ARG,
271                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my targetChild.");
272
273         SysTryReturn(NID_UI,
274                                 child.GetParent() == this, E_INVALID_ARG,
275                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my child.");
276
277         r = GetCore().MoveChildBefore(targetChild.GetCore(), child.GetCore());
278         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
279
280         r = __controlPublics.Remove(child.GetPublic());
281         SysAssert(r == E_SUCCESS);
282
283         r = __controlPublics.IndexOf(targetChild.GetPublic(), index);
284         SysAssert(r == E_SUCCESS);
285
286         r = __controlPublics.InsertAt(child.GetPublic(), index);
287         SysAssert(r == E_SUCCESS);
288
289         return E_SUCCESS;
290 }
291
292 Tizen::Base::Collection::IList*
293 _ContainerImpl::GetChildrenPublic(void) const
294 {
295         ClearLastResult();
296         return const_cast <LinkedList*>(&__controlPublics);
297 }
298
299 // E_OUT_OF_RANGE
300 _ControlImpl*
301 _ContainerImpl::GetChild(int index) const
302 {
303         ClearLastResult();
304
305         const Control* pControl = static_cast <const Control*>(__controlPublics.GetAt(index));
306         result r = GetLastResult();
307         if (IsFailed(r))
308         {
309                 SysAssert(r == E_OUT_OF_RANGE); // I can't beleve Tizen::Base.
310                 SysLogException(NID_UI,
311                                  E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The specified index is out of range (index = %d, count = %d.)",
312                                  index, GetChildCount());
313
314                 return null;
315         }
316
317         SysAssert(pControl);
318
319         return const_cast <_ControlImpl*>(_ControlImpl::GetInstance(*pControl));
320 }
321
322 _ControlImpl*
323 _ContainerImpl::SearchControlByName(const Tizen::Base::String& name, bool recursive, bool searchMyself) const
324 {
325         ClearLastResult();
326
327         if (searchMyself == true || (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat()))
328         {
329                 if (name.CompareTo(GetName()) == 0)
330                 {
331                         return const_cast <_ContainerImpl*>(this);
332                 }
333         }
334
335         _ControlImpl* pChildFound = null;
336         for (int i = 0; i < __controlPublics.GetCount(); ++i)
337         {
338                 _ControlImpl* pChild = GetChild(i);
339
340                 SysAssert(pChild);
341                 if (pChild == null)
342                 {
343                         continue;
344                 }
345
346                 _ContainerImpl* pChildAsContainer = dynamic_cast <_ContainerImpl*>(pChild);
347                 if (pChildAsContainer && recursive)
348                 {
349                         pChildFound = pChildAsContainer->SearchControlByName(name, true, true);
350                         if (pChildFound != null)
351                         {
352                                 break;
353                         }
354                 }
355                 else if (name.CompareTo(pChild->GetName()) == 0)
356                 {
357                         pChildFound = pChild;
358                         break;
359                 }
360         }
361
362         return pChildFound;
363 }
364
365 // [ToDo] Check if the public Container leaves the out-param index as it is.
366 int
367 _ContainerImpl::GetChildIndex(const _ControlImpl* pChild) const
368 {
369         int index = -1;
370
371         result r = __controlPublics.IndexOf(pChild->GetPublic(), index);
372         if (IsFailed(r))
373         {
374                 SysAssert(r == E_OBJ_NOT_FOUND); // I can't beleve Tizen::Base.
375                 SysLogException(NID_UI, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The control is not a child of this container.");
376                 return -1;
377         }
378
379         return index;
380 }
381
382 int
383 _ContainerImpl::GetChildCount(void) const
384 {
385         ClearLastResult();
386         return __controlPublics.GetCount();
387 }
388
389 Layout*
390 _ContainerImpl::GetPublicPortraitLayoutN(void) const
391 {
392         ClearLastResult();
393
394         Layout* pLayout = _LayoutImpl::CreatePublicLayoutN(__portraitLayout);
395         result r = GetLastResult();
396         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
397
398         return pLayout;
399 }
400
401 Layout*
402 _ContainerImpl::GetPublicLandscapeLayoutN(void) const
403 {
404         ClearLastResult();
405
406         Layout* pLayout = _LayoutImpl::CreatePublicLayoutN(__landscapeLayout);
407         result r = GetLastResult();
408         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
409
410         return pLayout;
411 }
412
413 Layout*
414 _ContainerImpl::GetPublicLayoutN(void) const
415 {
416         return (GetCore().GetOrientation() == _CONTROL_ORIENTATION_LANDSCAPE) ?
417                    GetPublicLandscapeLayoutN() : GetPublicPortraitLayoutN();
418 }
419
420 result
421 _ContainerImpl::SetChildAt(const _ControlImpl* pChild, int index)
422 {
423         ClearLastResult();
424         result r = E_SUCCESS;
425
426         SysTryReturn(NID_UI,
427                                 pChild, E_INVALID_ARG,
428                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
429
430         // In API 2.0, (0 <= index) was not checked but checked at the ArrayList::SetAt().
431         // So, I check the case here. No problem.
432         SysTryReturn(NID_UI,
433                                 (0 <= index && index < GetCore().GetChildCount()), E_OUT_OF_RANGE,
434                                 E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The specified index is out of range (index = %d, count = %d)",
435                                 index, GetCore().GetChildCount());
436
437         // [ToDo] 2.0 bug: The error should be E_INVALID_ARG.
438         // And I think this must be checked before the range check.
439         _ContainerImpl* pParent = pChild->GetParent();
440         SysTryReturn(NID_UI,
441                                 pParent == this, E_SYSTEM,
442                                 E_SYSTEM, "[E_SYSTEM] The container is not the parent of the specified control.");
443
444         int oldIndex = GetCore().GetChildIndex(pChild->GetCore());
445         SysAssert(GetLastResult() == E_SUCCESS);
446
447         if (index == oldIndex)
448         {
449                 return E_SUCCESS;
450         }
451
452         r = __controlPublics.SetAt(*pChild, index);
453         SysAssert(r == E_SUCCESS);
454
455         _Control* pTargetChild = GetCore().GetChild(index);
456         SysAssert(pTargetChild);
457
458         r = GetCore().MoveChildBefore(*pTargetChild, pChild->GetCore());
459         SysAssert(r == E_SUCCESS);
460
461         return E_SUCCESS;
462 }
463
464 bool
465 _ContainerImpl::IsAncestorOf(const _ControlImpl* pChild) const
466 {
467         SysTryReturn(NID_UI, pChild, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
468         return GetCore().IsAncestorOf(pChild->GetCore());
469 }
470
471 void
472 _ContainerImpl::OnDraw(void)
473 {
474         GetPublic().OnClearBackground();
475
476         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
477         {
478                 GetCore().OnDraw();
479         }
480
481         GetPublic().OnDraw();
482 }
483
484 void
485 _ContainerImpl::OnChangeLayout(_ControlOrientation orientation)
486 {
487         result r = E_SUCCESS;
488         _ControlImpl::OnChangeLayout(orientation);
489
490         if (orientation == _CONTROL_ORIENTATION_PORTRAIT && !__portraitLayout.IsNull())
491         {
492                 r = GetCore().SetCurrentLayout(__portraitLayout->GetCore());
493                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout as portrait");
494         }
495         else if (orientation == _CONTROL_ORIENTATION_LANDSCAPE && !__landscapeLayout.IsNull())
496         {
497                 r = GetCore().SetCurrentLayout(__landscapeLayout->GetCore());
498                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout as landscape.");
499         }
500 }
501
502 void
503 _ContainerImpl::OnVisibleStateChanging(void)
504 {
505         GetPublic().OnShowStateChanging(GetVisibleState());
506         _ControlImpl::OnVisibleStateChanging();
507 }
508
509 void
510 _ContainerImpl::OnVisibleStateChanged(void)
511 {
512         GetPublic().OnShowStateChanged(GetVisibleState());
513         _ControlImpl::OnVisibleStateChanged();
514 }
515
516 result
517 _ContainerImpl::OnBoundsChanging(const Rectangle& bounds)
518 {
519         GetPublic().OnBoundsChanging(__oldBounds, bounds);
520         return _ControlImpl::OnBoundsChanging(bounds);
521 }
522
523 void
524 _ContainerImpl::OnBoundsChanged(void)
525 {
526         GetPublic().OnBoundsChanged(__oldBounds, GetBounds());
527         _ControlImpl::OnBoundsChanged();
528 }
529
530 void
531 _ContainerImpl::OnEvaluateSize(Dimension& evaluatedSize)
532 {
533         GetPublic().OnEvaluateSize(evaluatedSize);
534         _ControlImpl::OnEvaluateSize(evaluatedSize);
535 }
536
537 void
538 _ContainerImpl::CallOnDraw(void)
539 {
540         if (!_AppInfo::IsOspCompat())
541         {
542                 GetCore().OnDraw();
543         }
544 }
545
546 void
547 _ContainerImpl::Initialize(Control* pPublic, _Control* pCore, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout)
548 {
549         result r = GetLastResult();
550         if (IsFailed(r))
551         {
552                 return;
553         }
554
555         _SharedPtr <Tizen::Ui::_LayoutImpl> spPortraitLayout;
556         _SharedPtr <Tizen::Ui::_LayoutImpl> spLandscapeLayout;
557
558         // Check if all or none
559         SysAssert(
560                 (pPublicPortraitLayout && pPublicLandscapeLayout) ||
561                 (!pPublicPortraitLayout && !pPublicLandscapeLayout)
562                 );
563
564         if (pPublicPortraitLayout)
565         {
566                 r = SetLayout(*pCore, _CONTROL_ORIENTATION_PORTRAIT, pPublicPortraitLayout);
567                 if (IsFailed(r))
568                 {
569                         return;
570                 }
571
572                 r = pCore->SetCurrentLayout(__portraitLayout->GetCore());
573                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout.");
574         }
575
576         if (pPublicLandscapeLayout)
577         {
578                 r = SetLayout(*pCore, _CONTROL_ORIENTATION_LANDSCAPE, pPublicLandscapeLayout);
579                 if (IsFailed(r))
580                 {
581                         return;
582                 }
583         }
584 }
585
586 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout)
587         : _ControlImpl(pPublic, pCore)
588 {
589         Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
590 }
591
592 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const Rectangle& bounds, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout, bool resizable, bool movable)
593         : _ControlImpl(pPublic, pCore)
594 {
595         result r = E_SUCCESS;
596
597         Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
598
599         r = GetLastResult();
600         if (IsFailed(r))
601         {
602                 return;
603         }
604
605         bool allOrNone = (pPublicPortraitLayout && pPublicLandscapeLayout) || (!pPublicPortraitLayout && !pPublicLandscapeLayout);
606         SysAssert(allOrNone);
607
608         r = SetBounds(bounds);
609         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
610
611         pCore->SetResizable(resizable);
612         pCore->SetMovable(movable);
613 }
614
615 result
616 _ContainerImpl::SetLayout(_Control& core, _ControlOrientation orientation, const Layout* pPublicLayout)
617 {
618         SysAssert(pPublicLayout);
619
620         result r = E_SUCCESS;
621
622         const char* orientationStatus = (orientation == _CONTROL_ORIENTATION_PORTRAIT) ?
623                                                                  "portrait" : "landscape";
624
625         _SharedPtr <Tizen::Ui::_LayoutImpl>& spLayout = (orientation == _CONTROL_ORIENTATION_PORTRAIT) ?
626                                                                  __portraitLayout : __landscapeLayout;
627
628         spLayout = _LayoutImpl::GetLayoutImpl(const_cast <Layout*>(pPublicLayout));
629         SysTryReturn(NID_UI,
630                                 !spLayout.IsNull(), E_INVALID_ARG,
631                                 E_INVALID_ARG, "[E_INVALID_ARG] The %s layout is invalid object", orientationStatus);
632
633         r = core.AddLayout(spLayout->GetCore());
634         if (IsFailed(r))
635         {
636                 switch (r)
637                 {
638                 case E_INVALID_ARG:
639                         SysLogException(NID_UI, E_INVALID_ARG, "[E_INVALID_ARG] The %s layout is already used.", orientationStatus);
640                         break;
641                 default:
642                         SysLogException(NID_UI, E_SYSTEM, "[E_SYSTEM] Failed to add the %s layout.", orientationStatus);
643                 }
644
645                 return r;
646         }
647
648         return E_SUCCESS;
649 }
650
651 bool
652 _ContainerImpl::IsChildAttachable(_ControlImpl& child) const
653 {
654         if (dynamic_cast <_WindowImpl*>(&child) != null)
655         {
656                 return false;
657         }
658
659         return true;
660 }
661
662
663 result
664 _ContainerImpl::SetControlAlwaysOnTop(Control& control, bool alwaysOnTop)
665 {
666         _ControlImpl* pChild = _ControlImpl::GetInstance(control);
667         SysTryReturn(NID_UI,
668                                 pChild, E_INVALID_ARG,
669                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
670
671         _Control& childCore = pChild->GetCore();
672         const bool atBottom = childCore.GetLayer() == _CONTROL_LAYER_CLIENT_BOTTOM;
673
674         if (atBottom && !alwaysOnTop)
675         {
676                 SysLogException(NID_UI, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The bottom child cannot be reset.");
677                 return E_INVALID_OPERATION;
678         }
679
680         return alwaysOnTop ?
681                    GetCore().SetChildAlwaysOnTop(childCore) :
682                    GetCore().ResetChildLayer(childCore);
683 }
684
685 result
686 _ContainerImpl::SetControlAlwaysAtBottom(Control& control, bool alwaysAtBottom)
687 {
688         _ControlImpl* pChild = _ControlImpl::GetInstance(control);
689         SysTryReturn(NID_UI,
690                                 pChild, E_INVALID_ARG,
691                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
692
693         _Control& childCore = pChild->GetCore();
694         const bool onTop = childCore.GetLayer() == _CONTROL_LAYER_CLIENT_TOP;
695
696         if (onTop && !alwaysAtBottom)
697         {
698                 SysLogException(NID_UI, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The top child cannot be reset.");
699                 return E_INVALID_OPERATION;
700         }
701
702         return alwaysAtBottom ?
703                    GetCore().SetChildAlwaysAtBottom(childCore) :
704                    GetCore().ResetChildLayer(childCore);
705 }
706
707 bool
708 _ContainerImpl::IsControlAlwaysAtBottom(const Control& control) const
709 {
710         const _ControlImpl* pChild = _ControlImpl::GetInstance(control);
711         SysTryReturn(NID_UI,
712                                 pChild, false,
713                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
714
715         SysTryReturn(NID_UI,
716                            pChild->GetParent() == this, false,
717                            E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not a child of this container.");
718
719         return pChild->GetCore().GetLayer() == _CONTROL_LAYER_CLIENT_BOTTOM;
720 }
721
722 bool
723 _ContainerImpl::IsControlAlwaysOnTop(const Control& control) const
724 {
725         const _ControlImpl* pChild = _ControlImpl::GetInstance(control);
726         SysTryReturn(NID_UI,
727                                 pChild, false,
728                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
729
730         SysTryReturn(NID_UI,
731                            pChild->GetParent() == this, false,
732                            E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not a child of this container.");
733
734         return pChild->GetCore().GetLayer() == _CONTROL_LAYER_CLIENT_TOP;
735 }
736
737 }} //Tizen::Ui