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
70 * Virtual destructor may only be called by Unreference()
72 virtual ~LayoutGroup();
75 LayoutGroup( const LayoutGroup& copy ) = delete;
76 LayoutGroup& operator=( const LayoutGroup& rhs ) = delete;
79 * @brief Add a layout child to this group.
81 * @param[in] layoutChild The child to add
82 * @return The layout id of this child.
84 Toolkit::LayoutGroup::LayoutId Add( LayoutItem& layoutChild ) override;
87 * @brief Remove a layout child from this group.
88 * @param[in] childId The layout child id
90 void Remove( Toolkit::LayoutGroup::LayoutId childId ) override;
93 * @brief Remove a layout child from this group
94 * @param[in] child The layout child
96 void Remove( LayoutItem& child ) override;
99 * @brief Insert a child to the parent
100 * @param[in] target The target item
101 * @param[in] child The item to insert to this layout parent
103 Toolkit::LayoutGroup::LayoutId Insert( LayoutItem& target, LayoutItem& child ) override;
106 * @brief Move a child to another position
107 * @param[in] target The target item
108 * @param[in] child The item to move
110 Toolkit::LayoutGroup::LayoutId Move( LayoutItem& target, LayoutItem& child ) override;
113 * @brief Move a child to back
114 * @param[in] child The item to move
116 Toolkit::LayoutGroup::LayoutId MoveBack( LayoutItem& child ) override;
119 * @brief Remove all layout children.
121 * @note This will not unparent owner's children
127 * @brief Get the number of children contained by this layout group
129 * @return the number of children
131 unsigned int GetChildCount() const;
134 * Get the child layout at the given index
136 LayoutItemPtr GetChildAt( unsigned int childIndex ) const;
139 * Get the child layout id of the given child
141 Toolkit::LayoutGroup::LayoutId GetChildId( LayoutItem& child ) const;
144 * @brief Get the layout child with the given layout id.
145 * @note child id's start at 1, and follow the insertion order
146 * @param[in] childId the layout id of the child within this group
147 * @return A pointer to the child layout
149 LayoutItemPtr GetChild( Toolkit::LayoutGroup::LayoutId childId ) const;
151 template <typename T>
152 LayoutItemPtr GetChild( T childId ) = delete; // Prevent implicit casting of int/uint to LayoutId
155 * Callback when child is added to container.
156 * Derived classes can use this to set their own child properties on the child layout's owner.
158 virtual void OnChildAdd( LayoutItem& child );
161 * Callback when child is removed from container.
163 virtual void OnChildRemove( LayoutItem& child );
166 * @brief Calculate the right measure spec for this child.
168 * Does the hard part of MeasureChildren: figuring out the MeasureSpec to
169 * pass to a particular child. This method figures out the right MeasureSpec
170 * for one dimension (height or width) of one child view.
172 * The goal is to combine information from our MeasureSpec with the
173 * LayoutParams of the child to get the best possible results. For example,
174 * if the this view knows its size (because its MeasureSpec has a mode of
175 * EXACTLY), and the child has indicated in its LayoutParams that it wants
176 * to be the same size as the parent, the parent should ask the child to
177 * layout given an exact size.
179 * @param measureSpec The requirements for this view
181 * @param padding The padding of this view for the current dimension
182 * and margins, if applicable
184 * @param childDimension How big the child wants to be in the
186 * @return a MeasureSpec for the child
188 static MeasureSpec GetChildMeasureSpec( MeasureSpec measureSpec,
189 LayoutLength padding,
190 LayoutLength childDimension );
194 * @brief Second stage initialization method for deriving classes to override
196 virtual void DoInitialize();
199 * @brief Method for derived classes to implement in order to register child
200 * property types with the container.
202 * @param[in] containerType The fully qualified typename of the container
204 virtual void DoRegisterChildProperties( const std::string& containerType );
207 * Create default child property values suitable for this layout group or derived layouter
209 virtual void GenerateDefaultChildPropertyValues( Handle child );
212 * Ask all of the children of this view to measure themselves, taking into
213 * account both the MeasureSpec requirements for this view and its padding.
214 * The heavy lifting is done in GetChildMeasureSpec.
216 * @param widthMeasureSpec The width requirements for this view
217 * @param heightMeasureSpec The height requirements for this view
219 virtual void MeasureChildren( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec );
222 * Ask one of the children of this view to measure itself, taking into
223 * account both the MeasureSpec requirements for this view and its padding.
224 * The heavy lifting is done in GetChildMeasureSpec.
226 * @param child The child to measure
227 * @param parentWidthMeasureSpec The width requirements for this view
228 * @param parentHeightMeasureSpec The height requirements for this view
230 virtual void MeasureChild( LayoutItemPtr child, MeasureSpec parentWidthMeasureSpec, MeasureSpec parentHeightMeasureSpec );
233 * Ask one of the children of this view to measure itself, taking into
234 * account both the MeasureSpec requirements for this view and its padding
235 * and margins. The child must have MarginLayoutParams The heavy lifting is
236 * done in GetChildMeasureSpec.
238 * @param child The child to measure
239 * @param parentWidthMeasureSpec The width requirements for this view
240 * @param widthUsed Extra space that has been used up by the parent
241 * horizontally (possibly by other children of the parent)
242 * @param parentHeightMeasureSpec The height requirements for this view
243 * @param heightUsed Extra space that has been used up by the parent
244 * vertically (possibly by other children of the parent)
246 virtual void MeasureChildWithMargins( LayoutItemPtr child,
247 MeasureSpec parentWidthMeasureSpec,
248 LayoutLength widthUsed,
249 MeasureSpec parentHeightMeasureSpec,
250 LayoutLength heightUsed );
254 * Second stage initialization for LayoutGroup only.
255 * This will call DoInitialize on most derived class.
257 void OnInitialize() override final;
260 * @copydoc LayoutItem::OnRegisterChildProperties()
262 void OnRegisterChildProperties( const std::string& containerType ) override final;
265 * @copydoc LayoutItem::OnUnparent
267 void OnUnparent() override final;
270 * Method to remove a child from this group
272 void RemoveChild( LayoutItem& item );
275 * Callback when child is added to owner
277 void ChildAddedToOwner( Actor child );
280 * Callback when child is removed from owner
282 void ChildRemovedFromOwner( Actor child );
285 * Callback when child order is changed
287 void ChildOrderChanged( Actor child );
290 * Callback when an owner property is set. Triggers a relayout if it's a child property
292 void OnOwnerPropertySet( Handle& handle, Property::Index index, Property::Value value );
295 * Callback when a child property is set on any given child
296 * @param[in] handle The handle to the child
297 * @param[in] index The index of the property that has been set
298 * @param[in] value The new value of the property
300 void OnSetChildProperties( Handle& handle, Property::Index index, Property::Value value );
303 * @brief Called when a layer animation state is changed.
305 void OnAnimationStateChanged( bool animateLayout ) override final;
308 class Impl; // Class declaration is public so we can add devel API's in the future
311 std::unique_ptr<Impl> mImpl; // The implementation data for this class.
312 SlotDelegate<LayoutGroup> mSlotDelegate; ///< Slot delegate allows this class to connect safely to signals
315 } //namespace Internal
317 inline Internal::LayoutGroup& GetImplementation( Dali::Toolkit::LayoutGroup& handle )
319 DALI_ASSERT_ALWAYS( handle && "LayoutGroup handle is empty" );
320 BaseObject& object = handle.GetBaseObject();
321 return static_cast< Internal::LayoutGroup& >( object );
324 inline const Internal::LayoutGroup& GetImplementation( const Dali::Toolkit::LayoutGroup& handle )
326 DALI_ASSERT_ALWAYS( handle && "LayoutGroup handle is empty" );
327 const BaseObject& object = handle.GetBaseObject();
328 return static_cast< const Internal::LayoutGroup& >( object );
334 #endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_GROUP_H