#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/layouting/absolute-layout.h>
#include <dali-toolkit/devel-api/layouting/linear-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
#include <../custom-layout.h>
END_TEST;
}
-
int UtcDaliLayouting_RemoveLayout01(void)
{
ToolkitTestApplication application;
END_TEST;
}
+
+int UtcDaliLayouting_LayoutChildren01(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliLayouting_LayoutChildren01");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ stage.Add( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ DevelControl::SetLayout( hbox, hboxLayout );
+ rootControl.Add( hbox );
+
+ DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 1, TEST_LOCATION );
+
+ tet_infoline("Test removal by setting empty layout to child container" );
+ DevelControl::SetLayout( hbox, LayoutItem{} );
+
+ DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 0, TEST_LOCATION );
+
+ auto& hboxImpl = GetImplementation( hboxLayout );
+ Handle empty;
+ DALI_TEST_EQUALS( hboxLayout.GetOwner(), empty, TEST_LOCATION );
+ DALI_TEST_EQUALS( (void*)hboxImpl.GetParent(), (void*)nullptr, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliLayouting_LayoutChildren02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliLayouting_LayoutChildren02");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ stage.Add( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ DevelControl::SetLayout( hbox, hboxLayout );
+ rootControl.Add( hbox );
+
+ DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 1, TEST_LOCATION );
+
+ tet_infoline("Test removal by removing child actor from parent container" );
+ hbox.Unparent();
+
+ DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 0, TEST_LOCATION );
+
+ auto& hboxImpl = GetImplementation( hboxLayout );
+ tet_infoline("Test child actor still has hbox layout " );
+ DALI_TEST_EQUALS( (bool)hboxLayout.GetOwner(), true, TEST_LOCATION );
+
+ tet_infoline("Test hbox layout has no parent " );
+ DALI_TEST_EQUALS( (void*)hboxImpl.GetParent(), (void*)nullptr, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliLayouting_LayoutChildren03(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliLayouting_LayoutChildren02");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ stage.Add( rootControl );
+
+ auto hbox = Control::New();
+ auto hboxLayout = LinearLayout::New();
+ DevelControl::SetLayout( hbox, hboxLayout );
+ rootControl.Add( hbox );
+
+ DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 1, TEST_LOCATION );
+
+ tet_infoline("Test removal by removing child layout from parent layout" );
+ absoluteLayout.Remove( hboxLayout );
+
+ DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 0, TEST_LOCATION );
+
+ auto& hboxImpl = GetImplementation( hboxLayout );
+
+ tet_infoline("Check child actor has orphaned layout (Moving child keeps old layout)");
+ DALI_TEST_EQUALS( hboxLayout.GetOwner(), hbox, TEST_LOCATION );
+ DALI_TEST_EQUALS( DevelControl::GetLayout(hbox), hboxLayout, TEST_LOCATION );
+
+ tet_infoline("Check orphaned layout has no parent");
+ DALI_TEST_EQUALS( (void*)hboxImpl.GetParent(), (void*)nullptr, TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+int UtcDaliLayouting_LayoutChildren04(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliLayouting_LayoutChildren03");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto rootControl = Control::New();
+ auto absoluteLayout = AbsoluteLayout::New();
+ DevelControl::SetLayout( rootControl, absoluteLayout );
+ stage.Add( rootControl );
+
+ auto hbox = Control::New();
+ tet_infoline("Test unparenting by adding child with no layout to parent (should auto-generate LayoutItem) ");
+ auto hboxLayout = LinearLayout::New();
+ rootControl.Add( hbox );
+
+ DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 1, TEST_LOCATION );
+
+ tet_infoline("Then setting a layout on the child container");
+ DevelControl::SetLayout( hbox, hboxLayout );
+
+ DALI_TEST_EQUALS( absoluteLayout.GetChildCount(), 1, TEST_LOCATION );
+
+ auto& hboxImpl = GetImplementation( hboxLayout );
+ auto& absImpl = GetImplementation( absoluteLayout );
+ DALI_TEST_EQUALS( hboxLayout.GetOwner(), Handle(hbox), TEST_LOCATION );
+ DALI_TEST_EQUALS( hboxImpl.GetParent(), (Dali::Toolkit::Internal::LayoutParent*)&absImpl, TEST_LOCATION );
+
+ END_TEST;
+}
$(devel_api_src_dir)/layouting/child-layout-data.h \
$(devel_api_src_dir)/layouting/flex-layout.h \
$(devel_api_src_dir)/layouting/linear-layout.h \
- $(devel_api_src_dir)/layouting/layout-item.h \
- $(devel_api_src_dir)/layouting/layout-item-impl.h \
+ $(devel_api_src_dir)/layouting/layout-child-impl.h \
$(devel_api_src_dir)/layouting/layout-controller.h \
$(devel_api_src_dir)/layouting/layout-group.h \
$(devel_api_src_dir)/layouting/layout-group-impl.h \
+ $(devel_api_src_dir)/layouting/layout-item.h \
+ $(devel_api_src_dir)/layouting/layout-item-impl.h \
$(devel_api_src_dir)/layouting/layout-length.h \
+ $(devel_api_src_dir)/layouting/layout-parent-impl.h \
$(devel_api_src_dir)/layouting/layout-size.h \
$(devel_api_src_dir)/layouting/measured-size.h \
- $(devel_api_src_dir)/layouting/layout-parent-impl.h \
$(devel_api_src_dir)/layouting/measure-spec.h
devel_api_magnifier_header_files = \
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_CHILD_H
+#define DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_CHILD_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+class LayoutParent;
+
+/**
+ * Interface that allows a layout to determine its layout parent.
+ *
+ * This is useful for LayoutItem to determine it's parent, without accessing
+ * via LayoutGroup, which is a subclass of LayoutItem (Super classes shouldn't
+ * know / care about derived classes)
+ */
+class DALI_TOOLKIT_API LayoutChild
+{
+public:
+ /**
+ * Set the parent of this layout.
+ */
+ virtual void SetParent( LayoutParent* parent ) = 0;
+
+ /**
+ * Get the parent of this layout.
+ */
+ virtual LayoutParent* GetParent() = 0;
+
+protected:
+ virtual ~LayoutChild()
+ {
+ }
+};
+
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
+
+#endif //DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_CHILD_H
{
if( iter->layoutId == childId )
{
- OnChildRemove( *iter->child.Get() );
+ RemoveChild( *iter->child.Get() );
mImpl->mChildren.erase(iter);
break;
}
{
if( iter->child.Get() == &child )
{
- OnChildRemove( *iter->child.Get() );
+ RemoveChild( *iter->child.Get() );
mImpl->mChildren.erase(iter);
break;
}
{
for( auto iter = mImpl->mChildren.begin() ; iter != mImpl->mChildren.end() ; )
{
- OnChildRemove( *iter->child.Get() );
+ RemoveChild( *iter->child.Get() );
iter = mImpl->mChildren.erase(iter);
}
}
{
// Remove children
RemoveAll();
+}
- // Remove myself from parent
- LayoutParent* parent = GetParent();
- if( parent )
- {
- LayoutGroupPtr parentGroup( dynamic_cast< LayoutGroup* >( parent ) );
- if( parentGroup )
- {
- parentGroup->Remove( *this );
- }
- }
+void LayoutGroup::RemoveChild( LayoutItem& item )
+{
+ item.SetParent( nullptr );
+ OnChildRemove( item );
}
void LayoutGroup::ChildAddedToOwner( Actor child )
#include <dali/public-api/signals/connection-tracker.h>
#include <dali-toolkit/devel-api/layouting/child-layout-data.h>
#include <dali-toolkit/devel-api/layouting/layout-group.h>
+#include <dali-toolkit/devel-api/layouting/layout-parent-impl.h>
#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
namespace Dali
* position and size; it should then call Layout() on the child layout to layout the child and it's hierarchy.
*/
class DALI_TOOLKIT_API LayoutGroup : public LayoutItem,
+ public LayoutParent,
public ConnectionTracker
{
public:
* @param[in] layoutChild The child to add
* @return The layout id of this child.
*/
- Toolkit::LayoutGroup::LayoutId Add( LayoutItem& layoutChild );
+ Toolkit::LayoutGroup::LayoutId Add( LayoutItem& layoutChild ) override;
/**
* @brief Remove a layout child from this group.
* @param[in] childId The layout child id
*/
- void Remove( Toolkit::LayoutGroup::LayoutId childId );
+ void Remove( Toolkit::LayoutGroup::LayoutId childId ) override;
/**
* @brief Remove a layout child from this group
* @param[in] child The layout child
*/
- void Remove( LayoutItem& child );
+ void Remove( LayoutItem& child ) override;
/**
* @brief Remove all layout children.
void OnUnparent() override final;
/**
+ * Method to remove a child from this group
+ */
+ void RemoveChild( LayoutItem& item );
+
+ /**
* Callback when child is added to owner
*/
void ChildAddedToOwner( Actor child );
#include <dali/public-api/object/type-registry-helper.h>
#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
#include <dali-toolkit/internal/layouting/layout-item-data-impl.h>
namespace
// Enable directly derived types to first remove children
OnUnparent();
+ // Remove myself from parent
+ LayoutParent* parent = GetParent();
+ if( parent )
+ {
+ parent->Remove( *this );
+ }
+
+ // Remove parent reference
+ SetParent(nullptr);
+
// Last, clear owner
mImpl->mOwner = NULL;
}
#include <dali/public-api/actors/actor-enumerations.h>
#include <dali-toolkit/devel-api/layouting/child-layout-data.h>
#include <dali-toolkit/devel-api/layouting/layout-item.h>
-#include <dali-toolkit/devel-api/layouting/layout-parent-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-child-impl.h>
#include <dali-toolkit/devel-api/layouting/layout-controller.h>
#include <dali-toolkit/devel-api/layouting/layout-size.h>
#include <dali-toolkit/devel-api/layouting/measure-spec.h>
* Base class for layouts.
*/
class DALI_TOOLKIT_API LayoutItem : public BaseObject,
- public LayoutParent
+ public LayoutChild
{
public:
/**
Handle GetOwner() const;
/**
- * @brief Unparent this layout from it's owner, and remove any layout children in derived types
+ * @brief Unparent this layout from it's parent, remove it from it's owner
+ * and remove any layout children in derived types.
*/
void Unparent();
static LayoutLength GetDefaultSize( LayoutLength size, MeasureSpec measureSpec );
/**
- * @copydoc LayoutParent::SetParent
+ * @copydoc LayoutChild::SetParent
*/
- virtual void SetParent( LayoutParent* parent ) override;
+ void SetParent( LayoutParent* parent ) override;
/**
- * @copydoc LayoutParent::GetParent
+ * @copydoc LayoutChild::GetParent
*/
- virtual LayoutParent* GetParent() override;
+ LayoutParent* GetParent() override;
/**
* @brief Request that this layout is re-laid out.
{
namespace Internal
{
+class LayoutItem;
/**
- * Interface that allows a layout to determine its layout parent.
- *
- * Needed to prevent circular inheritance - most LayoutBases have a parent,
- * but parenting is provided by LayoutGroup, which is a sub-class of LayoutBase.
+ * Interface that defines a layout Parent. Enables a layout child to access
+ * methods on its parent, e.g. Remove (during unparenting)
*/
class DALI_TOOLKIT_API LayoutParent
{
public:
/**
- * Set the parent of this layout.
+ * @brief Add a child to the parent
+ * @param[in] item The item to add to this layout parent
*/
- virtual void SetParent( LayoutParent* parent ) = 0;
+ virtual Toolkit::LayoutGroup::LayoutId Add( LayoutItem& item ) = 0;
/**
- * Get the parent of this layout.
+ * @brief Remove a layout child from this group.
+ * @param[in] childId The layout child id
*/
- virtual LayoutParent* GetParent() = 0;
+ virtual void Remove( Toolkit::LayoutGroup::LayoutId childId ) = 0;
+
+ /**
+ * @brief Remove a child from this parent
+ * @param[in] item The item to remove from this layout parent
+ */
+ virtual void Remove( LayoutItem& item ) = 0;
protected:
virtual ~LayoutParent()
};
+
} // namespace Internal
} // namespace Toolkit
} // namespace Dali