Merge "Bug fix in GetfallbackFont , check same style font" into tizen_2.1
[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 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_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();
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         _ContainerImpl* pParent = GetParent();
184         if (pParent)
185         {
186                 r = pParent->RemoveChild(this, true);
187         }
188         else
189         {
190                 RemoveAllChildren(true);
191                 delete &GetPublic();
192                 return E_SUCCESS;
193         }
194         return r;
195 }
196
197 // E_INVALID_ARG, E_OBJ_NOT_FOUND
198 result
199 _ContainerImpl::RemoveChild(_ControlImpl* pChild, bool deallocate)
200 {
201         ClearLastResult();
202         result r = E_SUCCESS;
203
204         SysTryReturn(NID_UI,
205                                 pChild != null, E_INVALID_ARG,
206                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
207
208         if (pChild->GetCore().GetArea() == _CONTROL_AREA_SYSTEM)
209         {
210                 return E_SUCCESS;
211         }
212
213         GetChildIndex(pChild); 
214         r = GetLastResult();
215         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
216
217         r = GetCore().DetachChild(pChild->GetCore());
218         SysAssert(r == E_SUCCESS);
219
220         r = __controlPublics.Remove(pChild->GetPublic(), deallocate);
221         SysAssert(r == E_SUCCESS);
222
223         return E_SUCCESS;
224 }
225
226 result
227 _ContainerImpl::RemoveChild(int index)
228 {
229         ClearLastResult();
230         result r = E_SUCCESS;
231
232         _ControlImpl* pChild = GetChild(index); // Find child control.
233         r = GetLastResult();
234         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
235
236         SysAssert(pChild);
237         SysTryReturn(NID_UI, pChild, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The child to remove is null.");
238
239         GetCore().DetachChild(pChild->GetCore());
240         SysAssert(GetLastResult() == E_SUCCESS);
241
242         r = __controlPublics.Remove(pChild->GetPublic(), true);
243         SysAssert(r == E_SUCCESS);
244
245         return E_SUCCESS;
246 }
247
248 void
249 _ContainerImpl::RemoveAllChildren(bool detachSystemChild)
250 {
251         ClearLastResult();
252         result r = E_SUCCESS;
253
254         GetCore().DetachAllChildren(detachSystemChild);
255         SysAssert(GetLastResult() == E_SUCCESS);
256
257         if (detachSystemChild)
258         {
259                 __controlPublics.RemoveAll(true);
260         }
261         else
262         {
263                 int childCount = __controlPublics.GetCount();
264                 int itemIndex = 0;
265
266                 while (childCount--)
267                 {
268                         _ControlImpl* pControl = GetChild(itemIndex);
269                         if (pControl->GetCore().GetArea() == _CONTROL_AREA_SYSTEM)
270                         {
271                                 itemIndex++;
272                                 continue;
273                         }
274
275                         r = __controlPublics.Remove(pControl->GetPublic(), true);
276                         SysAssert(r == E_SUCCESS);
277                 }
278         }
279 }
280
281 result
282 _ContainerImpl::MoveChildToTop(const _ControlImpl& child)
283 {
284         ClearLastResult();
285         result r = E_SUCCESS;
286
287         SysTryReturn(NID_UI,
288                                 child.GetParent() == this, E_INVALID_ARG,
289                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my child.");
290
291         r = GetCore().MoveChildToTop(child.GetCore());
292         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
293
294         r = __controlPublics.Remove(child.GetPublic());
295         SysAssert(r == E_SUCCESS);
296
297         r = __controlPublics.Add(child.GetPublic());
298         SysAssert(r == E_SUCCESS);
299
300         return E_SUCCESS;
301 }
302
303 result
304 _ContainerImpl::MoveChildBefore(const _ControlImpl& targetChild, const _ControlImpl& child)
305 {
306         ClearLastResult();
307         result r = E_SUCCESS;
308         int index = -1;
309
310         SysTryReturn(NID_UI,
311                                 targetChild.GetParent() == this, E_INVALID_ARG,
312                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my targetChild.");
313
314         SysTryReturn(NID_UI,
315                                 child.GetParent() == this, E_INVALID_ARG,
316                                 E_INVALID_ARG, "[E_INVALID_ARG] Not my child.");
317
318         r = GetCore().MoveChildBefore(targetChild.GetCore(), child.GetCore());
319         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
320
321         r = __controlPublics.Remove(child.GetPublic());
322         SysAssert(r == E_SUCCESS);
323
324         r = __controlPublics.IndexOf(targetChild.GetPublic(), index);
325         SysAssert(r == E_SUCCESS);
326
327         r = __controlPublics.InsertAt(child.GetPublic(), index);
328         SysAssert(r == E_SUCCESS);
329
330         return E_SUCCESS;
331 }
332
333 Tizen::Base::Collection::IList*
334 _ContainerImpl::GetChildrenPublic(void) const
335 {
336         ClearLastResult();
337         return const_cast <LinkedList*>(&__controlPublics);
338 }
339
340 // E_OUT_OF_RANGE
341 _ControlImpl*
342 _ContainerImpl::GetChild(int index) const
343 {
344         ClearLastResult();
345
346         const Control* pControl = static_cast <const Control*>(__controlPublics.GetAt(index));
347         result r = GetLastResult();
348         if (IsFailed(r))
349         {
350                 SysAssert(r == E_OUT_OF_RANGE); // I can't beleve Tizen::Base.
351                 SysLogException(NID_UI,
352                                  E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The specified index is out of range (index = %d, count = %d.)",
353                                  index, GetChildCount());
354
355                 return null;
356         }
357
358         SysAssert(pControl);
359
360         return const_cast <_ControlImpl*>(_ControlImpl::GetInstance(*pControl));
361 }
362
363 _ControlImpl*
364 _ContainerImpl::SearchControlByName(const Tizen::Base::String& name, bool recursive, bool searchMyself) const
365 {
366         ClearLastResult();
367
368         if (searchMyself == true || (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat()))
369         {
370                 if (name.CompareTo(GetName()) == 0)
371                 {
372                         return const_cast <_ContainerImpl*>(this);
373                 }
374         }
375
376         _ControlImpl* pChildFound = null;
377         for (int i = 0; i < __controlPublics.GetCount(); ++i)
378         {
379                 _ControlImpl* pChild = GetChild(i);
380
381                 SysAssert(pChild);
382                 if (pChild == null)
383                 {
384                         continue;
385                 }
386
387                 _ContainerImpl* pChildAsContainer = dynamic_cast <_ContainerImpl*>(pChild);
388                 if (pChildAsContainer && recursive)
389                 {
390                         pChildFound = pChildAsContainer->SearchControlByName(name, true, true);
391                         if (pChildFound != null)
392                         {
393                                 break;
394                         }
395                 }
396                 else if (name.CompareTo(pChild->GetName()) == 0)
397                 {
398                         pChildFound = pChild;
399                         break;
400                 }
401         }
402
403         return pChildFound;
404 }
405
406 // [ToDo] Check if the public Container leaves the out-param index as it is.
407 int
408 _ContainerImpl::GetChildIndex(const _ControlImpl* pChild) const
409 {
410         int index = -1;
411
412         result r = __controlPublics.IndexOf(pChild->GetPublic(), index);
413         if (IsFailed(r))
414         {
415                 SysAssert(r == E_OBJ_NOT_FOUND);
416                 SysLogException(NID_UI, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The control is not a child of this container.");
417                 return -1;
418         }
419
420         return index;
421 }
422
423 int
424 _ContainerImpl::GetChildCount(void) const
425 {
426         ClearLastResult();
427         return __controlPublics.GetCount();
428 }
429
430 Layout*
431 _ContainerImpl::GetPublicPortraitLayoutN(void) const
432 {
433         ClearLastResult();
434
435         Layout* pLayout = _LayoutImpl::CreatePublicLayoutN(__portraitLayout);
436         result r = GetLastResult();
437         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
438
439         return pLayout;
440 }
441
442 Layout*
443 _ContainerImpl::GetPublicLandscapeLayoutN(void) const
444 {
445         ClearLastResult();
446
447         Layout* pLayout = _LayoutImpl::CreatePublicLayoutN(__landscapeLayout);
448         result r = GetLastResult();
449         SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
450
451         return pLayout;
452 }
453
454 Layout*
455 _ContainerImpl::GetPublicLayoutN(void) const
456 {
457         return (GetCore().GetOrientation() == _CONTROL_ORIENTATION_LANDSCAPE) ?
458                    GetPublicLandscapeLayoutN() : GetPublicPortraitLayoutN();
459 }
460
461 result
462 _ContainerImpl::SetChildAt(const _ControlImpl* pChild, int index)
463 {
464         ClearLastResult();
465         result r = E_SUCCESS;
466
467         SysTryReturn(NID_UI,
468                                 pChild, E_INVALID_ARG,
469                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
470
471         // In API 2.0, (0 <= index) was not checked but checked at the ArrayList::SetAt().
472         // So, I check the case here. No problem.
473         SysTryReturn(NID_UI,
474                                 (0 <= index && index < GetCore().GetChildCount()), E_OUT_OF_RANGE,
475                                 E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The specified index is out of range (index = %d, count = %d)",
476                                 index, GetCore().GetChildCount());
477
478         // [ToDo] 2.0 bug: The error should be E_INVALID_ARG.
479         // And I think this must be checked before the range check.
480         _ContainerImpl* pParent = pChild->GetParent();
481         SysTryReturn(NID_UI,
482                                 pParent == this, E_SYSTEM,
483                                 E_SYSTEM, "[E_SYSTEM] The container is not the parent of the specified control.");
484
485         int oldIndex = GetCore().GetChildIndex(pChild->GetCore());
486         SysAssert(GetLastResult() == E_SUCCESS);
487
488         if (index == oldIndex)
489         {
490                 return E_SUCCESS;
491         }
492
493         r = __controlPublics.SetAt(pChild->GetPublic(), index);
494         SysAssert(r == E_SUCCESS);
495
496         _Control* pTargetChild = GetCore().GetChild(index);
497         SysAssert(pTargetChild);
498
499         r = GetCore().MoveChildBefore(*pTargetChild, pChild->GetCore());
500         SysAssert(r == E_SUCCESS);
501
502         return E_SUCCESS;
503 }
504
505 bool
506 _ContainerImpl::IsAncestorOf(const _ControlImpl* pChild) const
507 {
508         SysTryReturn(NID_UI, pChild, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
509         return GetCore().IsAncestorOf(pChild->GetCore());
510 }
511
512 void
513 _ContainerImpl::OnDraw(void)
514 {
515         GetPublic().OnClearBackground();
516
517         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
518         {
519                 GetCore().OnDraw();
520         }
521
522         GetPublic().OnDraw();
523 }
524
525 void
526 _ContainerImpl::OnChangeLayout(_ControlOrientation orientation)
527 {
528         result r = E_SUCCESS;
529         _ControlImpl::OnChangeLayout(orientation);
530
531         if (orientation == _CONTROL_ORIENTATION_PORTRAIT && !__portraitLayout.IsNull())
532         {
533                 r = GetCore().SetCurrentLayout(__portraitLayout->GetCore());
534                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout as portrait");
535         }
536         else if (orientation == _CONTROL_ORIENTATION_LANDSCAPE && !__landscapeLayout.IsNull())
537         {
538                 r = GetCore().SetCurrentLayout(__landscapeLayout->GetCore());
539                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout as landscape.");
540         }
541 }
542
543 void
544 _ContainerImpl::OnVisibleStateChanging(void)
545 {
546         GetPublic().OnShowStateChanging(GetVisibleState());
547         _ControlImpl::OnVisibleStateChanging();
548 }
549
550 void
551 _ContainerImpl::OnVisibleStateChanged(void)
552 {
553         _ControlImpl::OnVisibleStateChanged();
554         GetPublic().OnShowStateChanged(GetVisibleState());
555 }
556
557 result
558 _ContainerImpl::OnBoundsChanging(const Rectangle& bounds)
559 {
560         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
561         if (pChild)
562         {
563                 GetPublic().OnBoundsChanging(_CoordinateSystemUtils::ConvertToInteger(__oldBounds), bounds);
564         }
565
566         return _ControlImpl::OnBoundsChanging(bounds);
567 }
568
569 result
570 _ContainerImpl::OnBoundsChanging(const FloatRectangle& bounds)
571 {
572         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
573         if (pChild)
574         {
575                 GetPublic().OnBoundsChanging(__oldBounds, bounds);
576         }
577         return _ControlImpl::OnBoundsChanging(bounds);
578 }
579
580 void
581 _ContainerImpl::OnBoundsChanged(void)
582 {
583         _ControlImpl::OnBoundsChanged();
584         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
585         if (pChild)
586         {
587                 GetPublic().OnBoundsChanged(_CoordinateSystemUtils::ConvertToInteger(__oldBounds), GetBounds());
588                 GetPublic().OnBoundsChanged(__oldBounds, GetBoundsF());
589         }
590 }
591
592 void
593 _ContainerImpl::OnEvaluateSize(Dimension& evaluatedSize)
594 {
595         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
596         if (pChild)
597         {
598                 GetPublic().OnEvaluateSize(evaluatedSize);
599         }
600         _ControlImpl::OnEvaluateSize(evaluatedSize);
601 }
602
603 bool
604 _ContainerImpl::OnEvaluateSize(FloatDimension& evaluatedSize)
605 {
606         _ContainerImpl* pChild = _ContainerImpl::GetInstance(GetPublic());
607         bool changed = false;
608         if (pChild)
609         {
610                 changed = GetPublic().OnEvaluateSize(evaluatedSize);
611         }
612         _ControlImpl::OnEvaluateSize(evaluatedSize);
613         return changed;
614 }
615
616 void
617 _ContainerImpl::CallOnDraw(void)
618 {
619         if (!_AppInfo::IsOspCompat())
620         {
621                 GetCore().OnDraw();
622         }
623 }
624
625 void
626 _ContainerImpl::Initialize(Control* pPublic, _Control* pCore, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout)
627 {
628         result r = GetLastResult();
629         if (IsFailed(r))
630         {
631                 return;
632         }
633
634         _SharedPtr <Tizen::Ui::_LayoutImpl> spPortraitLayout;
635         _SharedPtr <Tizen::Ui::_LayoutImpl> spLandscapeLayout;
636
637         // Check if all or none
638         SysAssert(
639                 (pPublicPortraitLayout && pPublicLandscapeLayout) ||
640                 (!pPublicPortraitLayout && !pPublicLandscapeLayout)
641                 );
642
643         if (pPublicPortraitLayout)
644         {
645                 r = SetLayout(*pCore, _CONTROL_ORIENTATION_PORTRAIT, pPublicPortraitLayout);
646                 if (IsFailed(r))
647                 {
648                         return;
649                 }
650
651                 r = pCore->SetCurrentLayout(__portraitLayout->GetCore());
652                 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout.");
653         }
654
655         if (pPublicLandscapeLayout)
656         {
657                 r = SetLayout(*pCore, _CONTROL_ORIENTATION_LANDSCAPE, pPublicLandscapeLayout);
658                 if (IsFailed(r))
659                 {
660                         return;
661                 }
662         }
663 }
664
665 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout)
666         : _ControlImpl(pPublic, pCore)
667 {
668         Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
669 }
670
671 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const Rectangle& bounds, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout, bool resizable, bool movable)
672         : _ControlImpl(pPublic, pCore)
673 {
674         result r = E_SUCCESS;
675
676         Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
677
678         r = GetLastResult();
679         if (IsFailed(r))
680         {
681                 return;
682         }
683
684         bool allOrNone = (pPublicPortraitLayout && pPublicLandscapeLayout) || (!pPublicPortraitLayout && !pPublicLandscapeLayout);
685         SysAssert(allOrNone);
686
687         r = SetBounds(bounds);
688         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
689
690         pCore->SetResizable(resizable);
691         pCore->SetMovable(movable);
692 }
693
694 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const FloatRectangle& bounds, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout, bool resizable, bool movable)
695         : _ControlImpl(pPublic, pCore)
696 {
697         result r = E_SUCCESS;
698
699         Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
700
701         r = GetLastResult();
702         if (IsFailed(r))
703         {
704                 return;
705         }
706
707         bool allOrNone = (pPublicPortraitLayout && pPublicLandscapeLayout) || (!pPublicPortraitLayout && !pPublicLandscapeLayout);
708         SysAssert(allOrNone);
709
710         r = SetBounds(bounds);
711         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
712
713         pCore->SetResizable(resizable);
714         pCore->SetMovable(movable);
715 }
716
717 result
718 _ContainerImpl::SetLayout(_Control& core, _ControlOrientation orientation, const Layout* pPublicLayout)
719 {
720         SysAssert(pPublicLayout);
721
722         result r = E_SUCCESS;
723
724         const char* orientationStatus = (orientation == _CONTROL_ORIENTATION_PORTRAIT) ?
725                                                                  "portrait" : "landscape";
726
727         _SharedPtr <Tizen::Ui::_LayoutImpl>& spLayout = (orientation == _CONTROL_ORIENTATION_PORTRAIT) ?
728                                                                  __portraitLayout : __landscapeLayout;
729
730         spLayout = _LayoutImpl::GetLayoutImpl(const_cast <Layout*>(pPublicLayout));
731         SysTryReturn(NID_UI,
732                                 !spLayout.IsNull(), E_INVALID_ARG,
733                                 E_INVALID_ARG, "[E_INVALID_ARG] The %s layout is invalid object", orientationStatus);
734
735         r = core.AddLayout(spLayout->GetCore());
736         if (IsFailed(r))
737         {
738                 switch (r)
739                 {
740                 case E_INVALID_ARG:
741                         SysLogException(NID_UI, E_INVALID_ARG, "[E_INVALID_ARG] The %s layout is already used.", orientationStatus);
742                         break;
743                 default:
744                         SysLogException(NID_UI, E_SYSTEM, "[E_SYSTEM] Failed to add the %s layout.", orientationStatus);
745                 }
746
747                 return r;
748         }
749
750         return E_SUCCESS;
751 }
752
753 bool
754 _ContainerImpl::IsChildAttachable(_ControlImpl& child) const
755 {
756         if (dynamic_cast <_WindowImpl*>(&child) != null)
757         {
758                 return false;
759         }
760
761         return true;
762 }
763
764
765 result
766 _ContainerImpl::SetControlAlwaysOnTop(Control& control, bool alwaysOnTop)
767 {
768         _ControlImpl* pChild = _ControlImpl::GetInstance(control);
769         SysTryReturn(NID_UI,
770                                 pChild, E_INVALID_ARG,
771                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
772
773         _Control& childCore = pChild->GetCore();
774         const bool atBottom = childCore.GetLayer() == _CONTROL_LAYER_CLIENT_BOTTOM;
775
776         if (atBottom && !alwaysOnTop)
777         {
778                 SysLogException(NID_UI, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The bottom child cannot be reset.");
779                 return E_INVALID_OPERATION;
780         }
781
782         return alwaysOnTop ?
783                    GetCore().SetChildAlwaysOnTop(childCore) :
784                    GetCore().ResetChildLayer(childCore);
785 }
786
787 result
788 _ContainerImpl::SetControlAlwaysAtBottom(Control& control, bool alwaysAtBottom)
789 {
790         _ControlImpl* pChild = _ControlImpl::GetInstance(control);
791         SysTryReturn(NID_UI,
792                                 pChild, E_INVALID_ARG,
793                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
794
795         _Control& childCore = pChild->GetCore();
796         const bool onTop = childCore.GetLayer() == _CONTROL_LAYER_CLIENT_TOP;
797
798         if (onTop && !alwaysAtBottom)
799         {
800                 SysLogException(NID_UI, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The top child cannot be reset.");
801                 return E_INVALID_OPERATION;
802         }
803
804         return alwaysAtBottom ?
805                    GetCore().SetChildAlwaysAtBottom(childCore) :
806                    GetCore().ResetChildLayer(childCore);
807 }
808
809 bool
810 _ContainerImpl::IsControlAlwaysAtBottom(const Control& control) const
811 {
812         const _ControlImpl* pChild = _ControlImpl::GetInstance(control);
813         SysTryReturn(NID_UI,
814                                 pChild, false,
815                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
816
817         SysTryReturn(NID_UI,
818                            pChild->GetParent() == this, false,
819                            E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not a child of this container.");
820
821         return pChild->GetCore().GetLayer() == _CONTROL_LAYER_CLIENT_BOTTOM;
822 }
823
824 bool
825 _ContainerImpl::IsControlAlwaysOnTop(const Control& control) const
826 {
827         const _ControlImpl* pChild = _ControlImpl::GetInstance(control);
828         SysTryReturn(NID_UI,
829                                 pChild, false,
830                                 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
831
832         SysTryReturn(NID_UI,
833                            pChild->GetParent() == this, false,
834                            E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not a child of this container.");
835
836         return pChild->GetCore().GetLayer() == _CONTROL_LAYER_CLIENT_TOP;
837 }
838
839 }} //Tizen::Ui