Merge "Changes needed for https://review.tizen.org/gerrit/#/c/191202/" into devel...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / layouting / layout-item-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_ITEM_H
2 #define DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_ITEM_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/object/base-object.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/public-api/actors/actor-enumerations.h>
25 #include <dali-toolkit/devel-api/layouting/child-layout-data.h>
26 #include <dali-toolkit/devel-api/layouting/layout-item.h>
27 #include <dali-toolkit/devel-api/layouting/layout-child-impl.h>
28 #include <dali-toolkit/devel-api/layouting/layout-controller.h>
29 #include <dali-toolkit/devel-api/layouting/layout-size.h>
30 #include <dali-toolkit/devel-api/layouting/measure-spec.h>
31 #include <dali-toolkit/devel-api/layouting/measured-size.h>
32
33 namespace Dali
34 {
35 namespace Toolkit
36 {
37 namespace Internal
38 {
39
40 class LayoutItem;
41 using LayoutItemPtr = IntrusivePtr<LayoutItem>;
42
43
44 /**
45  * Base class for layouts.
46  */
47 class DALI_TOOLKIT_API LayoutItem : public BaseObject,
48                                     public LayoutChild
49 {
50 public:
51   /**
52    * Constructor.
53    */
54   LayoutItem();
55
56 protected:
57   /**
58    * A reference counted object may only be deleted by calling Unreference()
59    */
60   virtual ~LayoutItem();
61
62 public:
63
64 /**
65    * @brief Construct
66    *
67    * @param[in] owner The owner (container view / child view / visual ) of this layout
68    * @return a new LayoutItem object
69    */
70   static LayoutItemPtr New( Handle& owner );
71
72   /**
73    * @brief Remove the default copy constructor
74    */
75   LayoutItem(const LayoutItem& copy)=delete;
76
77   /**
78    * @brief Remove the default assignment operator
79    */
80   LayoutItem& operator=(const LayoutItem& rhs)=delete;
81
82   /**
83    * @brief Initialize the layout with it's owner and owner's type name
84    * @param[in] owner a handle to the owner container
85    * @param[in] containerType the type name of the owner container
86    */
87   void Initialize( Handle& owner, const std::string& containerType );
88
89   /**
90    * @brief Get a handle to the owner of this layout
91    *
92    * @return a handle to the owner of this layout
93    */
94   Handle GetOwner() const;
95
96   /**
97    * @brief Unparent this layout from it's parent, remove it from it's owner
98    * and remove any layout children in derived types.
99    */
100   void Unparent();
101
102   /**
103    * @brief Set whether this layout should be animated or not
104    *
105    * @param[in] animateLayout True if the layout should be animated when applied
106    */
107   void SetAnimateLayout( bool animateLayout );
108
109   /**
110    * @brief Get whether this layout should be animated or not
111    *
112    * @return True if the layout should be animated when applied
113    */
114   bool IsLayoutAnimated() const;
115
116   /**
117    * @brief  This is called to find out how big a layout should be.
118    *
119    * The parent supplies constraint information in the width and height parameters.
120    *
121    * The actual measurement work of a layout is performed in
122    * {@link #OnMeasure(MeasureSpec, MeasureSpec)}, called by this method. Therefore, only
123    * {@link #OnMeasure(MeasureSpec, MeasureSpec)} can and must be overridden by subclasses.
124    *
125    * @param[in] widthMeasureSpec Horizontal space requirements as imposed by the parent
126    * @param[in] heightMeasureSpec Vertical space requirements as imposed by the parent
127    *
128    * @see #OnMeasure(MeasureSpec, MeasureSpec)
129    */
130   void Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec );
131
132   /**
133    * @brief Assign a size and position to a layout and all of its descendants.
134    *
135    * This is the second phase of the layout mechanism.  (The first is measuring). In this phase, each parent
136    * calls layout on all of its children to position them.  This is typically done using the child
137    * measurements that were stored in the measure pass.
138    *
139    * Derived classes with children should override OnLayout. In that method, they should call Layout on each
140    * of their children.
141    *
142    * @param[in] left position, relative to parent
143    * @param[in] top position, relative to parent
144    * @param[in] right position, relative to parent
145    * @param[in] bottom position, relative to parent
146    */
147   void Layout( LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom );
148
149   /**
150    * @brief Utility to return a default size.
151    *
152    * Uses the supplied size if the MeasureSpec imposed no constraints. Will get larger if allowed by the
153    * MeasureSpec.
154    *
155    * @param[in] size Default size for this layout
156    * @param[in] measureSpec Constraints imposed by the parent
157    * @return The size this layout should be.
158    */
159   static LayoutLength GetDefaultSize( LayoutLength size, MeasureSpec measureSpec );
160
161   /**
162    * @copydoc LayoutChild::SetParent
163    */
164   void SetParent( LayoutParent* parent ) override;
165
166   /**
167    * @copydoc LayoutChild::GetParent
168    */
169   LayoutParent* GetParent() override;
170
171   /**
172    * @brief Request that this layout is re-laid out.
173    *
174    * This will make this layout and all it's parent layouts dirty.
175    */
176   void RequestLayout();
177
178   /**
179    * @brief Predicate to determine if this layout has been requested to re-layout
180    *
181    * @return True if a layout request has occured on this layout
182    */
183   bool IsLayoutRequested() const;
184
185   /**
186    * @brief Set layout requested flag (mark the layout dirty).
187    */
188   void SetLayoutRequested();
189
190   /**
191    * @brief Checks if the Resize policy is being used for this LayoutItem
192    * @return true is ResizePolicy is used
193    */
194   bool IsResizePolicyRequired() const;
195
196   /**
197    * @brief Sets if the ResizePolicy is needed or not for this LayoutItem
198    * @param[in] resizeRequired true or false flag
199    */
200   void SetResizePolicyRequired( bool resizeRequired );
201
202   /**
203    * @brief Get the measured width (without any measurement flags).
204    *
205    * This method should be used only during measurement and layout calculations.
206    *
207    * Use {@link Dali::Actor::GetTargetSize()} to see how wide a control is after layout
208    */
209   LayoutLength GetMeasuredWidth() const;
210
211   /**
212    * @brief Get the measured height (without any measurement flags).
213    *
214    * This method should be used only during measurement and layout calculations.
215    *
216    * Use {@link Dali::Actor::GetTargetSize()} to see how high a control is after layout
217    */
218   LayoutLength GetMeasuredHeight() const;
219
220   /**
221    * @brief Get the measured width and state.
222    *
223    * This method should be used only during measurement and layout calculations.
224    *
225    * Use {@link Dali::Actor::GetTargetSize()} to see how wide a view is after layout
226    */
227   MeasuredSize GetMeasuredWidthAndState() const;
228
229   /**
230    * @brief Get the measured height and state.
231    *
232    * This method should be used only during measurement and layout calculations.
233    *
234    * Use {@link Dali::Actor::GetTargetSize()} to see how high a view is after layout
235    */
236   MeasuredSize GetMeasuredHeightAndState() const;
237
238   /**
239    * @brief Returns the suggested minimum width that the layout should use.
240    *
241    * This returns the maximum of the layout's minimum width and the background's minimum width
242    *
243    * When being used in {@link #OnMeasure()}, the caller should still
244    * ensure the returned width is within the requirements of the parent.
245    *
246    * @return The suggested minimum width of the layout.
247    */
248   LayoutLength GetSuggestedMinimumWidth() const;
249
250   /**
251    * @brief Returns the suggested minimum height that the layout should use.
252    *
253    * This returns the maximum of the layout's minimum height and the background's minimum height
254    *
255    * When being used in {@link #OnMeasure()}, the caller should still
256    * ensure the returned height is within the requirements of the parent.
257    *
258    * @return The suggested minimum height of the layout.
259    */
260   LayoutLength GetSuggestedMinimumHeight() const;
261
262   /**
263    * @brief Sets the minimum width of the layout.
264    *
265    * It is not guaranteed the layout will be able to achieve this minimum width (for example, if its parent
266    * layout constrains it with less available width).
267    *
268    * @param[in] minWidth The minimum width the layout will try to be, in pixels
269    *
270    * @see #GetMinimumWidth()
271    */
272   void SetMinimumWidth( LayoutLength minWidth );
273
274   /**
275    * @brief Sets the minimum height of the layout.
276    *
277    * It is not guaranteed the layout will be able to achieve this minimum height (for example, if its parent
278    * layout constrains it with less available height).
279    *
280    * @param[in] minHeight The minimum height the layout will try to be, in pixels
281    *
282    * @see #GetMinimumHeight()
283    */
284   void SetMinimumHeight( LayoutLength minHeight );
285
286   /**
287    * @brief Returns the minimum width of the layout.
288    *
289    * @return the minimum width the layout will try to be, in pixels
290    *
291    * @see #SetMinimumWidth(LayoutLength)
292    */
293   LayoutLength GetMinimumWidth() const;
294
295   /**
296    * @brief Returns the minimum height of the layout.
297    *
298    * @return the minimum height the layout will try to be, in pixels
299    *
300    * @see #SetMinimumHeight(LayoutLength)
301    */
302   LayoutLength GetMinimumHeight() const;
303
304   /**
305    * Get the padding information.
306    * @return The padding information
307    */
308   Extents GetPadding() const;
309
310   /**
311    * Get the margin information.
312    * @return The margin information
313    */
314   Extents GetMargin() const;
315
316 protected:
317   /**
318    * @brief Allow directly deriving classes to remove layout children when unparented
319    */
320   virtual void OnUnparent(){};
321
322   /**
323    * @brief Ensure direct derived types register their child properties with the owner
324    *
325    * @param[in] containerType The type name of the owner container
326    */
327   virtual void OnRegisterChildProperties( const std::string& containerType );
328
329   /**
330    * @brief Measure the layout and its content to determine the measured width and the
331    * measured height.
332    *
333    * This method is invoked by {@link #Measure(MeasureSpec, MeasureSpec)} and
334    * should be overridden by subclasses to provide accurate and efficient
335    * measurement of their contents.
336    *
337    * <strong>CONTRACT:</strong> When overriding this method, you
338    * <em>must</em> call {@link #SetMeasuredDimensions(MeasuredSize,MeasuredSize)} to store the
339    * measured width and height of this layout. Failure to do so will trigger an
340    * <code>IllegalStateException</code>, thrown by
341    * {@link #Measure(MeasureSpec,MeasureSpec)}. Calling the superclass'
342    * {@link #OnMeasure(MeasureSpec,MeasureSpec)} is a valid use.
343    *
344    * The base class implementation of measure defaults to the background size,
345    * unless a larger size is allowed by the MeasureSpec. Subclasses should
346    * override {@link #OnMeasure(MeasureSpec,MeasureSpec)} to provide better measurements of
347    * their content.
348    *
349    * If this method is overridden, it is the subclass's responsibility to make
350    * sure the measured height and width are at least the layout's minimum height
351    * and width ({@link #GetSuggestedMinimumHeight()} and
352    * {@link #GetSuggestedMinimumWidth()}).
353    *
354    * @param[in] widthMeasureSpec horizontal space requirements as imposed by the parent.
355    *                             The requirements are encoded with
356    *                             {@link MeasureSpec}.
357    * @param[in] heightMeasureSpec vertical space requirements as imposed by the parent.
358    *                              The requirements are encoded with
359    *                              {@link MeasureSpec}.
360    *
361    * @see #GetMeasuredWidth()
362    * @see #GetMeasuredHeight()
363    * @see #GetSuggestedMinimumHeight()
364    * @see #GetSuggestedMinimumWidth()
365    * @see MeasureSpec#GetMode(int)
366    * @see MeasureSpec#GetSize(int)
367    */
368   virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec );
369
370   /**
371    * @brief Called from Layout() when this layout should assign a size and position to each of its children.
372    *
373    * Derived classes with children should override this method and call Layout() on each of their children.
374    *
375    * @param[in] changed This is a new size or position for this layout
376    * @param[in] left Left position, relative to parent
377    * @param[in] top Top position, relative to parent
378    * @param[in] right Right position, relative to parent
379    * @param[in] bottom Bottom position, relative to parent
380    */
381   virtual void OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom );
382
383
384   /**
385    * @brief This method must be called by {@link #OnMeasure(MeasureSpec,MeasureSpec)} to store the
386    * measured width and measured height.
387    *
388    * Failing to do so will trigger an exception at measurement time.
389    *
390    * @param[in] measuredWidth The measured width of this layout. This may have a state of
391    * {@link MeasuredSize::MEASURED_SIZE_TOO_SMALL}
392    *
393    * @param[in] measuredHeight The measured height of this layout. This may have a state of
394    * {@link MeasuredSize::MEASURED_SIZE_TOO_SMALL}
395    */
396   void SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight );
397
398   /**
399    * @brief Utility to reconcile a desired size and state, with constraints imposed by a MeasureSpec.
400    *
401    * @param[in] size How big the layout wants to be.
402    * @param[in] measureSpec Constraints imposed by the parent.
403    * @param[in] childMeasuredState Size information bit mask for the layout's children.
404    *
405    * @return A measured size, which may indicate that it is too small.
406    */
407   static MeasuredSize ResolveSizeAndState( LayoutLength size, MeasureSpec measureSpec,
408                                            MeasuredSize::State childMeasuredState );
409
410   /**
411    * @brief Sets the frame (the size and position) of the layout onto it's owner
412    *
413    * @todo Consider instead, collating properties into LayoutCollector in order to set/animate them all
414    * in one block.
415    * @param[in] left The horizontal position of the left edge of this frame within the parent layout
416    * @param[in] top The vertical position of the top edge of this frame within the parent layout
417    * @param[in] right The horizontal position of the right edge of this frame within the parent layout
418    * @param[in] bottom The vertical position of the bottom edge of this frame within the parent layout
419    */
420   bool SetFrame( LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom );
421
422   /**
423    * Virtual method to inform derived classes when the layout size changed
424    * @param[in] newSize The new size of the layout
425    * @param[in] oldSize The old size of the layout
426    */
427   virtual void OnSizeChanged( LayoutSize newSize, LayoutSize oldSize );
428
429
430   /**
431    * @brief Initialization method for LayoutGroup to override
432    */
433   virtual void OnInitialize();
434
435   /**
436    * @brief Called when a layer animation state is changed.
437    */
438   virtual void OnAnimationStateChanged( bool animateLayout ) {}
439
440 private:
441   /**
442    * @brief Called to change the size of the layout.
443    *
444    * @param[in] newSize The new size of the layout
445    * @param[in] oldSize The old size of the layout
446    */
447   void SizeChange( LayoutSize newSize, LayoutSize oldSize );
448
449   /**
450    * @brief Triggered when a layout animation finished.
451    *
452    * @param[in] animation  A handle to the layout animation
453    */
454   void OnLayoutAnimationFinished( Animation& animation );
455
456   /**
457    * @brief Register child properties of layout with owner type.
458    *
459    * The Actor hierarchy uses these registered properties in the type
460    * system to ensure child custom properties are properly initialized.
461    *
462    * @param[in] containerType The type of the containing view (owner)
463    */
464   void RegisterChildProperties( const std::string& containerType );
465
466 public:
467   class Impl; // Class declaration is public so we can add devel API's in the future
468
469
470 private:
471   std::unique_ptr<Impl> mImpl; ///< Implementation class holds all the data
472   SlotDelegate<LayoutItem> mSlotDelegate;
473 };
474
475 } //namespace Internal
476
477 inline Internal::LayoutItem& GetImplementation( Dali::Toolkit::LayoutItem& handle )
478 {
479   DALI_ASSERT_ALWAYS( handle && "LayoutItem handle is empty" );
480   BaseObject& object = handle.GetBaseObject();
481   return static_cast< Internal::LayoutItem& >( object );
482 }
483
484 inline const Internal::LayoutItem& GetImplementation( const Dali::Toolkit::LayoutItem& handle )
485 {
486   DALI_ASSERT_ALWAYS( handle && "LayoutItem handle is empty" );
487   const BaseObject& object = handle.GetBaseObject();
488   return static_cast< const Internal::LayoutItem& >( object );
489 }
490
491 } //namespace Toolkit
492 } //namespace Dali
493
494 #endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_ITEM_H