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 Remove all layout children.
101 * @note This will not unparent owner's children
107 * @brief Get the number of children contained by this layout group
109 * @return the number of children
111 unsigned int GetChildCount() const;
114 * Get the child layout at the given index
116 LayoutItemPtr GetChildAt( unsigned int childIndex ) const;
119 * Get the child layout id of the given child
121 Toolkit::LayoutGroup::LayoutId GetChildId( LayoutItem& child ) const;
124 * @brief Get the layout child with the given layout id.
125 * @note child id's start at 1, and follow the insertion order
126 * @param[in] childId the layout id of the child within this group
127 * @return A pointer to the child layout
129 LayoutItemPtr GetChild( Toolkit::LayoutGroup::LayoutId childId ) const;
131 template <typename T>
132 LayoutItemPtr GetChild( T childId ) = delete; // Prevent implicit casting of int/uint to LayoutId
135 * Callback when child is added to container.
136 * Derived classes can use this to set their own child properties on the child layout's owner.
138 virtual void OnChildAdd( LayoutItem& child );
141 * Callback when child is removed from container.
143 virtual void OnChildRemove( LayoutItem& child );
146 * @brief Calculate the right measure spec for this child.
148 * Does the hard part of MeasureChildren: figuring out the MeasureSpec to
149 * pass to a particular child. This method figures out the right MeasureSpec
150 * for one dimension (height or width) of one child view.
152 * The goal is to combine information from our MeasureSpec with the
153 * LayoutParams of the child to get the best possible results. For example,
154 * if the this view knows its size (because its MeasureSpec has a mode of
155 * EXACTLY), and the child has indicated in its LayoutParams that it wants
156 * to be the same size as the parent, the parent should ask the child to
157 * layout given an exact size.
159 * @param measureSpec The requirements for this view
161 * @param padding The padding of this view for the current dimension
162 * and margins, if applicable
164 * @param childDimension How big the child wants to be in the
166 * @return a MeasureSpec for the child
168 static MeasureSpec GetChildMeasureSpec( MeasureSpec measureSpec,
169 LayoutLength padding,
170 LayoutLength childDimension );
174 * @brief Second stage initialization method for deriving classes to override
176 virtual void DoInitialize();
179 * @brief Method for derived classes to implement in order to register child
180 * property types with the container.
182 * @param[in] containerType The fully qualified typename of the container
184 virtual void DoRegisterChildProperties( const std::string& containerType );
187 * Create default child property values suitable for this layout group or derived layouter
189 virtual void GenerateDefaultChildPropertyValues( Handle child );
192 * Ask all of the children of this view to measure themselves, taking into
193 * account both the MeasureSpec requirements for this view and its padding.
194 * The heavy lifting is done in GetChildMeasureSpec.
196 * @param widthMeasureSpec The width requirements for this view
197 * @param heightMeasureSpec The height requirements for this view
199 virtual void MeasureChildren( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec );
202 * Ask one of the children of this view to measure itself, taking into
203 * account both the MeasureSpec requirements for this view and its padding.
204 * The heavy lifting is done in GetChildMeasureSpec.
206 * @param child The child to measure
207 * @param parentWidthMeasureSpec The width requirements for this view
208 * @param parentHeightMeasureSpec The height requirements for this view
210 virtual void MeasureChild( LayoutItemPtr child, MeasureSpec parentWidthMeasureSpec, MeasureSpec parentHeightMeasureSpec );
213 * Ask one of the children of this view to measure itself, taking into
214 * account both the MeasureSpec requirements for this view and its padding
215 * and margins. The child must have MarginLayoutParams The heavy lifting is
216 * done in GetChildMeasureSpec.
218 * @param child The child to measure
219 * @param parentWidthMeasureSpec The width requirements for this view
220 * @param widthUsed Extra space that has been used up by the parent
221 * horizontally (possibly by other children of the parent)
222 * @param parentHeightMeasureSpec The height requirements for this view
223 * @param heightUsed Extra space that has been used up by the parent
224 * vertically (possibly by other children of the parent)
226 virtual void MeasureChildWithMargins( LayoutItemPtr child,
227 MeasureSpec parentWidthMeasureSpec,
228 LayoutLength widthUsed,
229 MeasureSpec parentHeightMeasureSpec,
230 LayoutLength heightUsed );
234 * Second stage initialization for LayoutGroup only.
235 * This will call DoInitialize on most derived class.
237 void OnInitialize() override final;
240 * @copydoc LayoutItem::OnRegisterChildProperties()
242 void OnRegisterChildProperties( const std::string& containerType ) override final;
245 * @copydoc LayoutItem::OnUnparent
247 void OnUnparent() override final;
250 * Method to remove a child from this group
252 void RemoveChild( LayoutItem& item );
255 * Callback when child is added to owner
257 void ChildAddedToOwner( Actor child );
260 * Callback when child is removed from owner
262 void ChildRemovedFromOwner( Actor child );
265 * Callback when child order is changed
267 void ChildOrderChanged();
270 * Callback when an owner property is set. Triggers a relayout if it's a child property
272 void OnOwnerPropertySet( Handle& handle, Property::Index index, Property::Value value );
275 * Callback when a child property is set on any given child
276 * @param[in] handle The handle to the child
277 * @param[in] index The index of the property that has been set
278 * @param[in] value The new value of the property
280 void OnSetChildProperties( Handle& handle, Property::Index index, Property::Value value );
283 * @brief Called when a layer animation state is changed.
285 void OnAnimationStateChanged( bool animateLayout ) override final;
288 class Impl; // Class declaration is public so we can add devel API's in the future
291 std::unique_ptr<Impl> mImpl; // The implementation data for this class.
292 SlotDelegate<LayoutGroup> mSlotDelegate; ///< Slot delegate allows this class to connect safely to signals
295 } //namespace Internal
297 inline Internal::LayoutGroup& GetImplementation( Dali::Toolkit::LayoutGroup& handle )
299 DALI_ASSERT_ALWAYS( handle && "LayoutGroup handle is empty" );
300 BaseObject& object = handle.GetBaseObject();
301 return static_cast< Internal::LayoutGroup& >( object );
304 inline const Internal::LayoutGroup& GetImplementation( const Dali::Toolkit::LayoutGroup& handle )
306 DALI_ASSERT_ALWAYS( handle && "LayoutGroup handle is empty" );
307 const BaseObject& object = handle.GetBaseObject();
308 return static_cast< const Internal::LayoutGroup& >( object );
314 #endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_GROUP_H