1 #ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_GROUP_H
2 #define DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_GROUP_H
4 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <dali/public-api/common/intrusive-ptr.h>
22 #include <dali/public-api/actors/actor-enumerations.h>
23 #include <dali/public-api/signals/connection-tracker.h>
24 #include <dali-toolkit/devel-api/layouting/child-layout-data.h>
25 #include <dali-toolkit/devel-api/layouting/layout-group.h>
26 #include <dali-toolkit/devel-api/layouting/layout-parent-impl.h>
27 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
37 using LayoutGroupPtr = IntrusivePtr<LayoutGroup>;
40 * LayoutGroup is an abstract class that provides child layout management and basic measuring and layouting.
42 * Deriving classes should override LayoutItem::DoInitialize for second stage initialization,
43 * LayoutGroup::DoRegisterChildProperties to register child property types with the owner,
44 * LayoutGroup::OnChildAdd to apply default child property values to the child.
45 * Deriving classes may override LayoutGroup::OnChildRemove.
47 * Deriving classes must also override OnMeasure and OnLayout as follows:
49 * OnMeasure should measure each child using LayoutGroup::MeasureChildWithMargins or LayoutGroup::MeasureChild.
50 * We recommend calling LayoutItem::ResolveSizeAndState() to resolve measure specs.
51 * If some children don't fit, then they can be measured again with different MeasureSpecs as required.
53 * After measurement, the derived class must also call SetMeasuredDimensions to set it's own requested size.
55 * OnLayout should use it's own layout parameters and the measured children's size to determine the children's
56 * position and size; it should then call Layout() on the child layout to layout the child and it's hierarchy.
58 class DALI_TOOLKIT_API LayoutGroup : public LayoutItem,
60 public ConnectionTracker
64 * Constructor. Returns an initialized object
71 * @param[in] owner The owner (container view / child view / visual ) of this layout
72 * @return a new LayoutGroup object
74 static LayoutGroupPtr New( Handle& owner );
78 * Virtual destructor may only be called by Unreference()
80 virtual ~LayoutGroup();
83 LayoutGroup( const LayoutGroup& copy ) = delete;
84 LayoutGroup& operator=( const LayoutGroup& rhs ) = delete;
87 * @brief Add a layout child to this group.
89 * @param[in] layoutChild The child to add
90 * @return The layout id of this child.
92 Toolkit::LayoutGroup::LayoutId Add( LayoutItem& layoutChild ) override;
95 * @brief Remove a layout child from this group.
96 * @param[in] childId The layout child id
98 void Remove( Toolkit::LayoutGroup::LayoutId childId ) override;
101 * @brief Remove a layout child from this group
102 * @param[in] child The layout child
104 void Remove( LayoutItem& child ) override;
107 * @brief Insert a child to the parent
108 * @param[in] target The target item
109 * @param[in] child The item to insert to this layout parent
111 Toolkit::LayoutGroup::LayoutId Insert( LayoutItem& target, LayoutItem& child ) override;
114 * @brief Move a child to another position
115 * @param[in] target The target item
116 * @param[in] child The item to move
118 Toolkit::LayoutGroup::LayoutId Move( LayoutItem& target, LayoutItem& child ) override;
121 * @brief Move a child to back
122 * @param[in] child The item to move
124 Toolkit::LayoutGroup::LayoutId MoveBack( LayoutItem& child ) override;
127 * @brief Remove all layout children.
129 * @note This will not unparent owner's children
135 * @brief Get the number of children contained by this layout group
137 * @return the number of children
139 unsigned int GetChildCount() const;
142 * Get the child layout at the given index
144 LayoutItemPtr GetChildAt( unsigned int childIndex ) const;
147 * Get the child layout id of the given child
149 Toolkit::LayoutGroup::LayoutId GetChildId( LayoutItem& child ) const;
152 * @brief Get the layout child with the given layout id.
153 * @note child id's start at 1, and follow the insertion order
154 * @param[in] childId the layout id of the child within this group
155 * @return A pointer to the child layout
157 LayoutItemPtr GetChild( Toolkit::LayoutGroup::LayoutId childId ) const;
159 template <typename T>
160 LayoutItemPtr GetChild( T childId ) = delete; // Prevent implicit casting of int/uint to LayoutId
163 * Callback when child is added to container.
164 * Derived classes can use this to set their own child properties on the child layout's owner.
166 virtual void OnChildAdd( LayoutItem& child );
169 * Callback when child is removed from container.
171 virtual void OnChildRemove( LayoutItem& child );
174 * @brief Calculate the right measure spec for this child.
176 * Does the hard part of MeasureChildren: figuring out the MeasureSpec to
177 * pass to a particular child. This method figures out the right MeasureSpec
178 * for one dimension (height or width) of one child view.
180 * The goal is to combine information from our MeasureSpec with the
181 * LayoutParams of the child to get the best possible results. For example,
182 * if the this view knows its size (because its MeasureSpec has a mode of
183 * EXACTLY), and the child has indicated in its LayoutParams that it wants
184 * to be the same size as the parent, the parent should ask the child to
185 * layout given an exact size.
187 * @param measureSpec The requirements for this view
189 * @param padding The padding of this view for the current dimension
190 * and margins, if applicable
192 * @param childDimension How big the child wants to be in the
194 * @return a MeasureSpec for the child
196 static MeasureSpec GetChildMeasureSpec( MeasureSpec measureSpec,
197 LayoutLength padding,
198 LayoutLength childDimension );
202 * @brief Second stage initialization method for deriving classes to override
204 virtual void DoInitialize();
207 * @brief Method for derived classes to implement in order to register child
208 * property types with the container.
210 * @param[in] containerType The fully qualified typename of the container
212 virtual void DoRegisterChildProperties( const std::string& containerType );
215 * Create default child property values suitable for this layout group or derived layouter
217 virtual void GenerateDefaultChildPropertyValues( Handle child );
220 * Ask all of the children of this view to measure themselves, taking into
221 * account both the MeasureSpec requirements for this view and its padding.
222 * The heavy lifting is done in GetChildMeasureSpec.
224 * @param widthMeasureSpec The width requirements for this view
225 * @param heightMeasureSpec The height requirements for this view
227 virtual void MeasureChildren( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec );
230 * Ask one of the children of this view to measure itself, taking into
231 * account both the MeasureSpec requirements for this view and its padding.
232 * The heavy lifting is done in GetChildMeasureSpec.
234 * @param child The child to measure
235 * @param parentWidthMeasureSpec The width requirements for this view
236 * @param parentHeightMeasureSpec The height requirements for this view
238 virtual void MeasureChild( LayoutItemPtr child, MeasureSpec parentWidthMeasureSpec, MeasureSpec parentHeightMeasureSpec );
241 * Ask one of the children of this view to measure itself, taking into
242 * account both the MeasureSpec requirements for this view and its padding
243 * and margins. The child must have MarginLayoutParams The heavy lifting is
244 * done in GetChildMeasureSpec.
246 * @param child The child to measure
247 * @param parentWidthMeasureSpec The width requirements for this view
248 * @param widthUsed Extra space that has been used up by the parent
249 * horizontally (possibly by other children of the parent)
250 * @param parentHeightMeasureSpec The height requirements for this view
251 * @param heightUsed Extra space that has been used up by the parent
252 * vertically (possibly by other children of the parent)
254 virtual void MeasureChildWithMargins( LayoutItemPtr child,
255 MeasureSpec parentWidthMeasureSpec,
256 LayoutLength widthUsed,
257 MeasureSpec parentHeightMeasureSpec,
258 LayoutLength heightUsed );
260 * @copydoc LayoutItem::OnMeasure
262 virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) override;
265 * @copydoc LayoutItem::OnLayout
267 virtual void OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom ) override;
271 * Second stage initialization for LayoutGroup only.
272 * This will call DoInitialize on most derived class.
274 void OnInitialize() override final;
277 * @copydoc LayoutItem::OnRegisterChildProperties()
279 void OnRegisterChildProperties( const std::string& containerType ) override final;
282 * @copydoc LayoutItem::OnUnparent
284 void OnUnparent() override final;
287 * Method to remove a child from this group
289 void RemoveChild( LayoutItem& item );
292 * Callback when child is added to owner
294 void ChildAddedToOwner( Actor child );
297 * Implementation of ChildAddedToOwner
299 void ChildAddedToOwnerImpl( Actor child );
302 * Callback when child is removed from owner
304 void ChildRemovedFromOwner( Actor child );
307 * Callback when child order is changed
309 void ChildOrderChanged( Actor child );
312 * Callback when an owner property is set. Triggers a relayout if it's a child property
314 void OnOwnerPropertySet( Handle& handle, Property::Index index, Property::Value value );
317 * Callback when a child property is set on any given child
318 * @param[in] handle The handle to the child
319 * @param[in] index The index of the property that has been set
320 * @param[in] value The new value of the property
322 void OnSetChildProperties( Handle& handle, Property::Index index, Property::Value value );
325 * @brief Called when a layer animation state is changed.
327 void OnAnimationStateChanged( bool animateLayout ) override final;
330 class Impl; // Class declaration is public so we can add devel API's in the future
333 std::unique_ptr<Impl> mImpl; // The implementation data for this class.
334 SlotDelegate<LayoutGroup> mSlotDelegate; ///< Slot delegate allows this class to connect safely to signals
337 } //namespace Internal
339 inline Internal::LayoutGroup& GetImplementation( Dali::Toolkit::LayoutGroup& handle )
341 DALI_ASSERT_ALWAYS( handle && "LayoutGroup handle is empty" );
342 BaseObject& object = handle.GetBaseObject();
343 return static_cast< Internal::LayoutGroup& >( object );
346 inline const Internal::LayoutGroup& GetImplementation( const Dali::Toolkit::LayoutGroup& handle )
348 DALI_ASSERT_ALWAYS( handle && "LayoutGroup handle is empty" );
349 const BaseObject& object = handle.GetBaseObject();
350 return static_cast< const Internal::LayoutGroup& >( object );
356 #endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_GROUP_H