[dali_1.4.16] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / layouting / layout-group-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_GROUP_H
2 #define DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_GROUP_H
3 /*
4  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 #include <memory>
20
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>
28
29 namespace Dali
30 {
31 namespace Toolkit
32 {
33 namespace Internal
34 {
35
36 class LayoutGroup;
37 using LayoutGroupPtr = IntrusivePtr<LayoutGroup>;
38
39 /**
40  * LayoutGroup is an abstract class that provides child layout management and basic measuring and layouting.
41  *
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.
46  *
47  * Deriving classes must also override OnMeasure and OnLayout as follows:
48  *
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.
52  *
53  * After measurement, the derived class must also call SetMeasuredDimensions to set it's own requested size.
54  *
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.
57  */
58 class DALI_TOOLKIT_API LayoutGroup : public LayoutItem,
59                                      public LayoutParent,
60                                      public ConnectionTracker
61 {
62 public:
63   /**
64    * Constructor. Returns an initialized object
65    */
66   LayoutGroup();
67
68   /**
69    * @brief Construct
70    *
71    * @param[in] owner The owner (container view / child view / visual ) of this layout
72    * @return a new LayoutGroup object
73    */
74   static LayoutGroupPtr New( Handle& owner );
75
76 protected:
77   /**
78    * Virtual destructor may only be called by Unreference()
79    */
80   virtual ~LayoutGroup();
81
82 public:
83   LayoutGroup( const LayoutGroup& copy ) = delete;
84   LayoutGroup& operator=( const LayoutGroup& rhs ) = delete;
85
86   /**
87    * @brief Add a layout child to this group.
88    *
89    * @param[in] layoutChild The child to add
90    * @return The layout id of this child.
91    */
92   Toolkit::LayoutGroup::LayoutId Add( LayoutItem& layoutChild ) override;
93
94   /**
95    * @brief Remove a layout child from this group.
96    * @param[in] childId The layout child id
97    */
98   void Remove( Toolkit::LayoutGroup::LayoutId childId ) override;
99
100   /**
101    * @brief Remove a layout child from this group
102    * @param[in] child The layout child
103    */
104   void Remove( LayoutItem& child ) override;
105
106   /**
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
110    */
111   Toolkit::LayoutGroup::LayoutId Insert( LayoutItem& target, LayoutItem& child ) override;
112
113   /**
114    * @brief Remove all layout children.
115    *
116    * @note This will not unparent owner's children
117    */
118   void RemoveAll();
119
120
121   /**
122    * @brief Get the number of children contained by this layout group
123    *
124    * @return the number of children
125    */
126   unsigned int GetChildCount() const;
127
128   /**
129    * Get the child layout at the given index
130    */
131   LayoutItemPtr GetChildAt( unsigned int childIndex ) const;
132
133   /**
134    * Get the child layout id of the given child
135    */
136   Toolkit::LayoutGroup::LayoutId GetChildId( LayoutItem& child ) const;
137
138   /**
139    * @brief Get the layout child with the given layout id.
140    * @note child id's start at 1, and follow the insertion order
141    * @param[in] childId the layout id of the child within this group
142    * @return A pointer to the child layout
143    */
144   LayoutItemPtr GetChild( Toolkit::LayoutGroup::LayoutId childId ) const;
145
146   template <typename T>
147     LayoutItemPtr GetChild( T childId ) = delete; // Prevent implicit casting of int/uint to LayoutId
148
149   /**
150    * Callback when child is added to container.
151    * Derived classes can use this to set their own child properties on the child layout's owner.
152    */
153   virtual void OnChildAdd( LayoutItem& child );
154
155   /**
156    * Callback when child is removed from container.
157    */
158   virtual void OnChildRemove( LayoutItem& child );
159
160   /**
161    * @brief Calculate the right measure spec for this child.
162    *
163    * Does the hard part of MeasureChildren: figuring out the MeasureSpec to
164    * pass to a particular child. This method figures out the right MeasureSpec
165    * for one dimension (height or width) of one child view.
166    *
167    * The goal is to combine information from our MeasureSpec with the
168    * LayoutParams of the child to get the best possible results. For example,
169    * if the this view knows its size (because its MeasureSpec has a mode of
170    * EXACTLY), and the child has indicated in its LayoutParams that it wants
171    * to be the same size as the parent, the parent should ask the child to
172    * layout given an exact size.
173    *
174    * @param measureSpec The requirements for this view
175    *
176    * @param padding The padding of this view for the current dimension
177    *        and margins, if applicable
178    *
179    * @param childDimension How big the child wants to be in the
180    *        current dimension
181    * @return a MeasureSpec for the child
182    */
183   static MeasureSpec GetChildMeasureSpec( MeasureSpec measureSpec,
184                                           LayoutLength padding,
185                                           LayoutLength childDimension );
186
187 protected:
188   /**
189    * @brief Second stage initialization method for deriving classes to override
190    */
191   virtual void DoInitialize();
192
193   /**
194    * @brief Method for derived classes to implement in order to register child
195    * property types with the container.
196    *
197    * @param[in] containerType The fully qualified typename of the container
198    */
199   virtual void DoRegisterChildProperties( const std::string& containerType );
200
201   /**
202    * Create default child property values suitable for this layout group or derived layouter
203    */
204   virtual void GenerateDefaultChildPropertyValues( Handle child );
205
206   /**
207    * Ask all of the children of this view to measure themselves, taking into
208    * account both the MeasureSpec requirements for this view and its padding.
209    * The heavy lifting is done in GetChildMeasureSpec.
210    *
211    * @param widthMeasureSpec The width requirements for this view
212    * @param heightMeasureSpec The height requirements for this view
213    */
214   virtual void MeasureChildren( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec );
215
216   /**
217    * Ask one of the children of this view to measure itself, taking into
218    * account both the MeasureSpec requirements for this view and its padding.
219    * The heavy lifting is done in GetChildMeasureSpec.
220    *
221    * @param child The child to measure
222    * @param parentWidthMeasureSpec The width requirements for this view
223    * @param parentHeightMeasureSpec The height requirements for this view
224    */
225   virtual void MeasureChild( LayoutItemPtr child, MeasureSpec parentWidthMeasureSpec, MeasureSpec parentHeightMeasureSpec );
226
227   /**
228    * Ask one of the children of this view to measure itself, taking into
229    * account both the MeasureSpec requirements for this view and its padding
230    * and margins. The child must have MarginLayoutParams The heavy lifting is
231    * done in GetChildMeasureSpec.
232    *
233    * @param child The child to measure
234    * @param parentWidthMeasureSpec The width requirements for this view
235    * @param widthUsed Extra space that has been used up by the parent
236    *        horizontally (possibly by other children of the parent)
237    * @param parentHeightMeasureSpec The height requirements for this view
238    * @param heightUsed Extra space that has been used up by the parent
239    *        vertically (possibly by other children of the parent)
240    */
241   virtual void MeasureChildWithMargins( LayoutItemPtr child,
242                                         MeasureSpec parentWidthMeasureSpec,
243                                         LayoutLength widthUsed,
244                                         MeasureSpec parentHeightMeasureSpec,
245                                         LayoutLength heightUsed );
246   /**
247    * @copydoc LayoutItem::OnMeasure
248    */
249   virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) override;
250
251   /**
252    * @copydoc LayoutItem::OnLayout
253    */
254   virtual void OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom ) override;
255
256 private:
257   /**
258    * Second stage initialization for LayoutGroup only.
259    * This will call DoInitialize on most derived class.
260    */
261   void OnInitialize() override final;
262
263   /**
264    * @copydoc LayoutItem::OnRegisterChildProperties()
265    */
266   void OnRegisterChildProperties( const std::string& containerType ) override final;
267
268   /**
269    * @copydoc LayoutItem::OnUnparent
270    */
271   void OnUnparent() override final;
272
273   /**
274    * Method to remove a child from this group
275    */
276   void RemoveChild( LayoutItem& item );
277
278   /**
279    * Callback when child is added to owner
280    */
281   void ChildAddedToOwner( Actor child );
282
283   /**
284    * Implementation of ChildAddedToOwner
285    */
286   void ChildAddedToOwnerImpl( Actor child );
287
288   /**
289    * Callback when child is removed from owner
290    */
291   void ChildRemovedFromOwner( Actor child );
292
293   /**
294    * Callback when an owner property is set. Triggers a relayout if it's a child property
295    */
296   void OnOwnerPropertySet( Handle& handle, Property::Index index, Property::Value value );
297
298   /**
299    * Callback when a child property is set on any given child
300    * @param[in] handle The handle to the child
301    * @param[in] index The index of the property that has been set
302    * @param[in] value The new value of the property
303    */
304   void OnSetChildProperties( Handle& handle, Property::Index index, Property::Value value );
305
306   /**
307    * @brief Called when a layer animation state is changed.
308    */
309   void OnAnimationStateChanged( bool animateLayout ) override final;
310
311 public:
312   class Impl; // Class declaration is public so we can add devel API's in the future
313
314 private:
315   std::unique_ptr<Impl> mImpl; // The implementation data for this class.
316   SlotDelegate<LayoutGroup> mSlotDelegate; ///< Slot delegate allows this class to connect safely to signals
317 };
318
319 } //namespace Internal
320
321 inline Internal::LayoutGroup& GetImplementation( Dali::Toolkit::LayoutGroup& handle )
322 {
323   DALI_ASSERT_ALWAYS( handle && "LayoutGroup handle is empty" );
324   BaseObject& object = handle.GetBaseObject();
325   return static_cast< Internal::LayoutGroup& >( object );
326 }
327
328 inline const Internal::LayoutGroup& GetImplementation( const Dali::Toolkit::LayoutGroup& handle )
329 {
330   DALI_ASSERT_ALWAYS( handle && "LayoutGroup handle is empty" );
331   const BaseObject& object = handle.GetBaseObject();
332   return static_cast< const Internal::LayoutGroup& >( object );
333 }
334
335 }//namespace Toolkit
336 }//namespace Dali
337
338 #endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_GROUP_H