2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
9 // http://floralicense.org/license/
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.
18 * @file FUi_ContainerImpl.cpp
19 * @brief This is the implementation file for _ContainerImpl class.
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"
30 using namespace Tizen::App;
31 using namespace Tizen::Base;
32 using namespace Tizen::Base::Collection;
33 using namespace Tizen::Graphics;
35 namespace Tizen { namespace Ui {
38 _ContainerImpl::CreateContainerImplN(Container* pPublic)
42 _Control* pCore = _Control::CreateControlN();
43 result r = GetLastResult();
44 SysTryReturn(NID_UI, pCore, null, r, "[%s] Propagating.", GetErrorMessage(r));
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));
54 _ContainerImpl::CreateContainerImplN(Container* pPublic, const Rectangle& bounds,
55 const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout,
56 bool resizable, bool movable)
60 _Control* pCore = _Control::CreateControlN();
61 SysTryReturn(NID_UI, pCore, null, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(r));
63 _ContainerImpl* pImpl =
64 new (std::nothrow) _ContainerImpl(pPublic, pCore, bounds,
65 pPublicPortraitLayout, pPublicLandscapeLayout,
67 r = CheckConstruction(pCore, pImpl);
68 SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
77 _ContainerImpl::GetInstance(Container& container)
79 return static_cast <_ContainerImpl*> (container._pControlImpl);
83 _ContainerImpl::GetInstance(const Container& container)
85 return static_cast <const _ContainerImpl*> (container._pControlImpl);
88 _ContainerImpl::~_ContainerImpl(void)
99 _ContainerImpl::GetPublicClassName(void) const
101 return "Tizen::Ui::Container";
105 _ContainerImpl::GetPublic(void) const
107 return static_cast <const Container&>(_ControlImpl::GetPublic());
111 _ContainerImpl::GetPublic(void)
113 return static_cast <Container&>(_ControlImpl::GetPublic());
116 // E_INVALID_ARG, E_OUT_OF_MEMORY
118 _ContainerImpl::AddChild(_ControlImpl* pChild, bool transferOwnership)
121 result r = E_SUCCESS;
124 pChild != null, E_INVALID_ARG,
125 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
128 IsChildAttachable(*pChild), E_INVALID_ARG,
129 E_INVALID_ARG, "[E_INVALID_ARG] %s cannot be a child of %s.",
130 pChild->GetPublicClassName(), GetPublicClassName());
132 _ContainerImpl* pOldParent = pChild->GetParent();
135 (pOldParent != this), E_INVALID_ARG,
136 E_INVALID_ARG, "[E_INVALID_ARG] The child control is already attached to this container.");
139 pOldParent == null, E_INVALID_ARG,
140 E_INVALID_ARG, "[E_INVALID_ARG] Unable to add the child which already has another parent.");
142 r = __controlPublics.Add(pChild->GetPublic());
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;
150 r = GetCore().AttachChild(pChild->GetCore());
151 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] propagated.", GetErrorMessage(r));
156 // E_INVALID_ARG, E_OBJ_NOT_FOUND
158 _ContainerImpl::RemoveChild(_ControlImpl* pChild, bool deallocate)
161 result r = E_SUCCESS;
164 pChild != null, E_INVALID_ARG,
165 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
167 if (pChild->GetCore().GetArea() == _CONTROL_AREA_SYSTEM)
172 GetChildIndex(pChild);
174 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
176 r = GetCore().DetachChild(pChild->GetCore());
177 SysAssert(r == E_SUCCESS);
179 r = __controlPublics.Remove(pChild->GetPublic(), deallocate);
180 SysAssert(r == E_SUCCESS);
186 _ContainerImpl::RemoveChild(int index)
189 result r = E_SUCCESS;
191 _ControlImpl* pChild = GetChild(index); // Find child control.
193 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
196 SysTryReturn(NID_UI, pChild, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The child to remove is null.");
198 GetCore().DetachChild(pChild->GetCore());
199 SysAssert(GetLastResult() == E_SUCCESS);
201 r = __controlPublics.Remove(pChild->GetPublic(), true);
202 SysAssert(r == E_SUCCESS);
208 _ContainerImpl::RemoveAllChildren(bool detachSystemChild)
211 result r = E_SUCCESS;
213 GetCore().DetachAllChildren(detachSystemChild);
214 SysAssert(GetLastResult() == E_SUCCESS);
216 if (detachSystemChild)
218 __controlPublics.RemoveAll(true);
222 int childCount = __controlPublics.GetCount();
227 _ControlImpl* pControl = GetChild(itemIndex);
228 if (pControl->GetCore().GetArea() == _CONTROL_AREA_SYSTEM)
234 r = __controlPublics.Remove(pControl->GetPublic(), true);
235 SysAssert(r == E_SUCCESS);
241 _ContainerImpl::MoveChildToTop(const _ControlImpl& child)
244 result r = E_SUCCESS;
247 child.GetParent() == this, E_INVALID_ARG,
248 E_INVALID_ARG, "[E_INVALID_ARG] Not my child.");
250 r = GetCore().MoveChildToTop(child.GetCore());
251 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
253 r = __controlPublics.Remove(child.GetPublic());
254 SysAssert(r == E_SUCCESS);
256 r = __controlPublics.Add(child.GetPublic());
257 SysAssert(r == E_SUCCESS);
263 _ContainerImpl::MoveChildBefore(const _ControlImpl& targetChild, const _ControlImpl& child)
266 result r = E_SUCCESS;
270 targetChild.GetParent() == this, E_INVALID_ARG,
271 E_INVALID_ARG, "[E_INVALID_ARG] Not my targetChild.");
274 child.GetParent() == this, E_INVALID_ARG,
275 E_INVALID_ARG, "[E_INVALID_ARG] Not my child.");
277 r = GetCore().MoveChildBefore(targetChild.GetCore(), child.GetCore());
278 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
280 r = __controlPublics.Remove(child.GetPublic());
281 SysAssert(r == E_SUCCESS);
283 r = __controlPublics.IndexOf(targetChild.GetPublic(), index);
284 SysAssert(r == E_SUCCESS);
286 r = __controlPublics.InsertAt(child.GetPublic(), index);
287 SysAssert(r == E_SUCCESS);
292 Tizen::Base::Collection::IList*
293 _ContainerImpl::GetChildrenPublic(void) const
296 return const_cast <LinkedList*>(&__controlPublics);
301 _ContainerImpl::GetChild(int index) const
305 const Control* pControl = static_cast <const Control*>(__controlPublics.GetAt(index));
306 result r = GetLastResult();
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());
319 return const_cast <_ControlImpl*>(_ControlImpl::GetInstance(*pControl));
323 _ContainerImpl::SearchControlByName(const Tizen::Base::String& name, bool recursive, bool searchMyself) const
327 if (searchMyself == true || (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat()))
329 if (name.CompareTo(GetName()) == 0)
331 return const_cast <_ContainerImpl*>(this);
335 _ControlImpl* pChildFound = null;
336 for (int i = 0; i < __controlPublics.GetCount(); ++i)
338 _ControlImpl* pChild = GetChild(i);
346 _ContainerImpl* pChildAsContainer = dynamic_cast <_ContainerImpl*>(pChild);
347 if (pChildAsContainer && recursive)
349 pChildFound = pChildAsContainer->SearchControlByName(name, true, true);
350 if (pChildFound != null)
355 else if (name.CompareTo(pChild->GetName()) == 0)
357 pChildFound = pChild;
365 // [ToDo] Check if the public Container leaves the out-param index as it is.
367 _ContainerImpl::GetChildIndex(const _ControlImpl* pChild) const
371 result r = __controlPublics.IndexOf(pChild->GetPublic(), index);
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.");
383 _ContainerImpl::GetChildCount(void) const
386 return __controlPublics.GetCount();
390 _ContainerImpl::GetPublicPortraitLayoutN(void) const
394 Layout* pLayout = _LayoutImpl::CreatePublicLayoutN(__portraitLayout);
395 result r = GetLastResult();
396 SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
402 _ContainerImpl::GetPublicLandscapeLayoutN(void) const
406 Layout* pLayout = _LayoutImpl::CreatePublicLayoutN(__landscapeLayout);
407 result r = GetLastResult();
408 SysTryReturn(NID_UI, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
414 _ContainerImpl::GetPublicLayoutN(void) const
416 return (GetCore().GetOrientation() == _CONTROL_ORIENTATION_LANDSCAPE) ?
417 GetPublicLandscapeLayoutN() : GetPublicPortraitLayoutN();
421 _ContainerImpl::SetChildAt(const _ControlImpl* pChild, int index)
424 result r = E_SUCCESS;
427 pChild, E_INVALID_ARG,
428 E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
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.
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());
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();
441 pParent == this, E_SYSTEM,
442 E_SYSTEM, "[E_SYSTEM] The container is not the parent of the specified control.");
444 int oldIndex = GetCore().GetChildIndex(pChild->GetCore());
445 SysAssert(GetLastResult() == E_SUCCESS);
447 if (index == oldIndex)
452 r = __controlPublics.SetAt(*pChild, index);
453 SysAssert(r == E_SUCCESS);
455 _Control* pTargetChild = GetCore().GetChild(index);
456 SysAssert(pTargetChild);
458 r = GetCore().MoveChildBefore(*pTargetChild, pChild->GetCore());
459 SysAssert(r == E_SUCCESS);
465 _ContainerImpl::IsAncestorOf(const _ControlImpl* pChild) const
467 SysTryReturn(NID_UI, pChild, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified child is not constructed.");
468 return GetCore().IsAncestorOf(pChild->GetCore());
472 _ContainerImpl::OnDraw(void)
474 GetPublic().OnClearBackground();
476 if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
481 GetPublic().OnDraw();
485 _ContainerImpl::OnChangeLayout(_ControlOrientation orientation)
487 result r = E_SUCCESS;
488 _ControlImpl::OnChangeLayout(orientation);
490 if (orientation == _CONTROL_ORIENTATION_PORTRAIT && !__portraitLayout.IsNull())
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");
495 else if (orientation == _CONTROL_ORIENTATION_LANDSCAPE && !__landscapeLayout.IsNull())
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.");
503 _ContainerImpl::OnVisibleStateChanging(void)
505 GetPublic().OnShowStateChanging(GetVisibleState());
506 _ControlImpl::OnVisibleStateChanging();
510 _ContainerImpl::OnVisibleStateChanged(void)
512 GetPublic().OnShowStateChanged(GetVisibleState());
513 _ControlImpl::OnVisibleStateChanged();
517 _ContainerImpl::OnBoundsChanging(const Rectangle& bounds)
519 GetPublic().OnBoundsChanging(__oldBounds, bounds);
520 return _ControlImpl::OnBoundsChanging(bounds);
524 _ContainerImpl::OnBoundsChanged(void)
526 GetPublic().OnBoundsChanged(__oldBounds, GetBounds());
527 _ControlImpl::OnBoundsChanged();
531 _ContainerImpl::OnEvaluateSize(Dimension& evaluatedSize)
533 GetPublic().OnEvaluateSize(evaluatedSize);
534 _ControlImpl::OnEvaluateSize(evaluatedSize);
538 _ContainerImpl::CallOnDraw(void)
540 if (!_AppInfo::IsOspCompat())
547 _ContainerImpl::Initialize(Control* pPublic, _Control* pCore, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout)
549 result r = GetLastResult();
555 _SharedPtr <Tizen::Ui::_LayoutImpl> spPortraitLayout;
556 _SharedPtr <Tizen::Ui::_LayoutImpl> spLandscapeLayout;
558 // Check if all or none
560 (pPublicPortraitLayout && pPublicLandscapeLayout) ||
561 (!pPublicPortraitLayout && !pPublicLandscapeLayout)
564 if (pPublicPortraitLayout)
566 r = SetLayout(*pCore, _CONTROL_ORIENTATION_PORTRAIT, pPublicPortraitLayout);
572 r = pCore->SetCurrentLayout(__portraitLayout->GetCore());
573 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to set up the current layout.");
576 if (pPublicLandscapeLayout)
578 r = SetLayout(*pCore, _CONTROL_ORIENTATION_LANDSCAPE, pPublicLandscapeLayout);
586 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout)
587 : _ControlImpl(pPublic, pCore)
589 Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
592 _ContainerImpl::_ContainerImpl(Control* pPublic, _Control* pCore, const Rectangle& bounds, const Layout* pPublicPortraitLayout, const Layout* pPublicLandscapeLayout, bool resizable, bool movable)
593 : _ControlImpl(pPublic, pCore)
595 result r = E_SUCCESS;
597 Initialize(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
605 bool allOrNone = (pPublicPortraitLayout && pPublicLandscapeLayout) || (!pPublicPortraitLayout && !pPublicLandscapeLayout);
606 SysAssert(allOrNone);
608 r = SetBounds(bounds);
609 SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
611 pCore->SetResizable(resizable);
612 pCore->SetMovable(movable);
616 _ContainerImpl::SetLayout(_Control& core, _ControlOrientation orientation, const Layout* pPublicLayout)
618 SysAssert(pPublicLayout);
620 result r = E_SUCCESS;
622 const char* orientationStatus = (orientation == _CONTROL_ORIENTATION_PORTRAIT) ?
623 "portrait" : "landscape";
625 _SharedPtr <Tizen::Ui::_LayoutImpl>& spLayout = (orientation == _CONTROL_ORIENTATION_PORTRAIT) ?
626 __portraitLayout : __landscapeLayout;
628 spLayout = _LayoutImpl::GetLayoutImpl(const_cast <Layout*>(pPublicLayout));
630 !spLayout.IsNull(), E_INVALID_ARG,
631 E_INVALID_ARG, "[E_INVALID_ARG] The %s layout is invalid object", orientationStatus);
633 r = core.AddLayout(spLayout->GetCore());
639 SysLogException(NID_UI, E_INVALID_ARG, "[E_INVALID_ARG] The %s layout is already used.", orientationStatus);
642 SysLogException(NID_UI, E_SYSTEM, "[E_SYSTEM] Failed to add the %s layout.", orientationStatus);
652 _ContainerImpl::IsChildAttachable(_ControlImpl& child) const
654 if (dynamic_cast <_WindowImpl*>(&child) != null)
664 _ContainerImpl::SetControlAlwaysOnTop(Control& control, bool alwaysOnTop)
666 _ControlImpl* pChild = _ControlImpl::GetInstance(control);
668 pChild, E_INVALID_ARG,
669 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
671 _Control& childCore = pChild->GetCore();
672 const bool atBottom = childCore.GetLayer() == _CONTROL_LAYER_CLIENT_BOTTOM;
674 if (atBottom && !alwaysOnTop)
676 SysLogException(NID_UI, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The bottom child cannot be reset.");
677 return E_INVALID_OPERATION;
681 GetCore().SetChildAlwaysOnTop(childCore) :
682 GetCore().ResetChildLayer(childCore);
686 _ContainerImpl::SetControlAlwaysAtBottom(Control& control, bool alwaysAtBottom)
688 _ControlImpl* pChild = _ControlImpl::GetInstance(control);
690 pChild, E_INVALID_ARG,
691 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
693 _Control& childCore = pChild->GetCore();
694 const bool onTop = childCore.GetLayer() == _CONTROL_LAYER_CLIENT_TOP;
696 if (onTop && !alwaysAtBottom)
698 SysLogException(NID_UI, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The top child cannot be reset.");
699 return E_INVALID_OPERATION;
702 return alwaysAtBottom ?
703 GetCore().SetChildAlwaysAtBottom(childCore) :
704 GetCore().ResetChildLayer(childCore);
708 _ContainerImpl::IsControlAlwaysAtBottom(const Control& control) const
710 const _ControlImpl* pChild = _ControlImpl::GetInstance(control);
713 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
716 pChild->GetParent() == this, false,
717 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not a child of this container.");
719 return pChild->GetCore().GetLayer() == _CONTROL_LAYER_CLIENT_BOTTOM;
723 _ContainerImpl::IsControlAlwaysOnTop(const Control& control) const
725 const _ControlImpl* pChild = _ControlImpl::GetInstance(control);
728 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not constructed.");
731 pChild->GetParent() == this, false,
732 E_INVALID_ARG, "[E_INVALID_ARG] The specified chlid control is not a child of this container.");
734 return pChild->GetCore().GetLayer() == _CONTROL_LAYER_CLIENT_TOP;