1 #ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_ITEM_H
2 #define DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_ITEM_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/object/base-object.h>
23 #include <dali/public-api/object/property-map.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/actors/actor-enumerations.h>
26 #include <dali/public-api/animation/animation.h>
27 #include <dali-toolkit/devel-api/layouting/child-layout-data.h>
28 #include <dali-toolkit/devel-api/layouting/layout-item.h>
29 #include <dali-toolkit/devel-api/layouting/layout-child-impl.h>
30 #include <dali-toolkit/devel-api/layouting/layout-controller.h>
31 #include <dali-toolkit/devel-api/layouting/layout-size.h>
32 #include <dali-toolkit/devel-api/layouting/measure-spec.h>
33 #include <dali-toolkit/devel-api/layouting/measured-size.h>
45 using LayoutItemPtr = IntrusivePtr<LayoutItem>;
47 class LayoutTransitionData;
48 using LayoutTransitionDataPtr = IntrusivePtr<LayoutTransitionData>;
51 * Base class for layouts.
53 class DALI_TOOLKIT_API LayoutItem : public BaseObject,
64 * A reference counted object may only be deleted by calling Unreference()
66 virtual ~LayoutItem();
73 * @param[in] owner The owner (container view / child view / visual ) of this layout
74 * @return a new LayoutItem object
76 static LayoutItemPtr New( Handle& owner );
79 * @brief Remove the default copy constructor
81 LayoutItem(const LayoutItem& copy)=delete;
84 * @brief Remove the default assignment operator
86 LayoutItem& operator=(const LayoutItem& rhs)=delete;
89 * @brief Initialize the layout with it's owner and owner's type name
90 * @param[in] owner a handle to the owner container
91 * @param[in] containerType the type name of the owner container
93 void Initialize( Handle& owner, const std::string& containerType );
96 * @brief Get a handle to the owner of this layout
98 * @return a handle to the owner of this layout
100 Handle GetOwner() const;
103 * @brief Unparent this layout from it's parent, remove it from it's owner
104 * and remove any layout children in derived types.
109 * @brief Set whether this layout should be animated or not
111 * @param[in] animateLayout True if the layout should be animated when applied
113 void SetAnimateLayout( bool animateLayout );
116 * @brief Get whether this layout should be animated or not
118 * @return True if the layout should be animated when applied
120 bool IsLayoutAnimated() const;
123 * @brief Get the default transition
125 * @return The default transition
127 LayoutTransitionDataPtr GetDefaultTransition();
130 * @brief Set the layout transition data
131 * @param[in] layoutTransitionType The type of the transition
132 * @param[in] layoutTransitionDataPtr The transition data pointer
134 void SetTransitionData( int layoutTransitionType, LayoutTransitionDataPtr layoutTransitionDataPtr );
137 * @brief Get the transition data
138 * @param[in] layoutTransitionType The type of the transition
140 * @return The transition
142 LayoutTransitionDataPtr GetTransitionData( int layoutTransitionType ) const;
145 * @brief This is called to find out how big a layout should be.
147 * The parent supplies constraint information in the width and height parameters.
149 * The actual measurement work of a layout is performed in
150 * {@link #OnMeasure(MeasureSpec, MeasureSpec)}, called by this method. Therefore, only
151 * {@link #OnMeasure(MeasureSpec, MeasureSpec)} can and must be overridden by subclasses.
153 * @param[in] widthMeasureSpec Horizontal space requirements as imposed by the parent
154 * @param[in] heightMeasureSpec Vertical space requirements as imposed by the parent
156 * @see #OnMeasure(MeasureSpec, MeasureSpec)
158 void Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec );
161 * @brief Assign a size and position to a layout and all of its descendants.
163 * This is the second phase of the layout mechanism. (The first is measuring). In this phase, each parent
164 * calls layout on all of its children to position them. This is typically done using the child
165 * measurements that were stored in the measure pass.
167 * Derived classes with children should override OnLayout. In that method, they should call Layout on each
170 * @param[in] left position, relative to parent
171 * @param[in] top position, relative to parent
172 * @param[in] right position, relative to parent
173 * @param[in] bottom position, relative to parent
175 void Layout( LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom );
178 * @brief Utility to return a default size.
180 * Uses the supplied size if the MeasureSpec imposed no constraints. Will get larger if allowed by the
183 * @param[in] size Default size for this layout
184 * @param[in] measureSpec Constraints imposed by the parent
185 * @return The size this layout should be.
187 static LayoutLength GetDefaultSize( LayoutLength size, MeasureSpec measureSpec );
190 * @copydoc LayoutChild::SetParent
192 void SetParent( LayoutParent* parent ) override;
195 * @copydoc LayoutChild::GetParent
197 LayoutParent* GetParent() override;
200 * @brief Request that this layout is re-laid out.
202 * This will make this layout and all it's parent layouts dirty.
204 void RequestLayout();
207 * @brief Request that this layout is re-laid out with particular transition.
208 * @param[in] layoutTranstionType The transition type
210 * This will make this layout and all it's parent layouts dirty and set the transition queued.
212 void RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutTranstionType );
215 * @brief Request that this layout is re-laid out with particular transition.
216 * @param[in] layoutTranstionType The transition type
217 * @param[in] gainedChild The gained owners's child due to add/remove or focus gained/lost
218 * @param[in] lostChild The lost owners's child due to add/remove or focus gained/lost
220 * This will make this layout and all it's parent layouts dirty and set the transition queued.
222 void RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutTranstionType, Actor gainedChild, Actor lostChild );
225 * @brief Predicate to determine if this layout has been requested to re-layout
227 * @return True if a layout request has occured on this layout
229 bool IsLayoutRequested() const;
232 * @brief Set layout requested flag (mark the layout dirty).
234 void SetLayoutRequested();
237 * @brief Checks if the Resize policy is being used for this LayoutItem
238 * @return true is ResizePolicy is used
240 bool IsResizePolicyRequired() const;
243 * @brief Sets if the ResizePolicy is needed or not for this LayoutItem
244 * @param[in] resizeRequired true or false flag
246 void SetResizePolicyRequired( bool resizeRequired );
249 * @brief Get the measured width (without any measurement flags).
251 * This method should be used only during measurement and layout calculations.
253 * Use {@link Dali::Actor::GetTargetSize()} to see how wide a control is after layout
255 LayoutLength GetMeasuredWidth() const;
258 * @brief Get the measured height (without any measurement flags).
260 * This method should be used only during measurement and layout calculations.
262 * Use {@link Dali::Actor::GetTargetSize()} to see how high a control is after layout
264 LayoutLength GetMeasuredHeight() const;
267 * @brief Get the measured width and state.
269 * This method should be used only during measurement and layout calculations.
271 * Use {@link Dali::Actor::GetTargetSize()} to see how wide a view is after layout
273 MeasuredSize GetMeasuredWidthAndState() const;
276 * @brief Get the measured height and state.
278 * This method should be used only during measurement and layout calculations.
280 * Use {@link Dali::Actor::GetTargetSize()} to see how high a view is after layout
282 MeasuredSize GetMeasuredHeightAndState() const;
285 * @brief Returns the suggested minimum width that the layout should use.
287 * This returns the maximum of the layout's minimum width and the background's minimum width
289 * When being used in {@link #OnMeasure()}, the caller should still
290 * ensure the returned width is within the requirements of the parent.
292 * @return The suggested minimum width of the layout.
294 LayoutLength GetSuggestedMinimumWidth() const;
297 * @brief Returns the suggested minimum height that the layout should use.
299 * This returns the maximum of the layout's minimum height and the background's minimum height
301 * When being used in {@link #OnMeasure()}, the caller should still
302 * ensure the returned height is within the requirements of the parent.
304 * @return The suggested minimum height of the layout.
306 LayoutLength GetSuggestedMinimumHeight() const;
309 * @brief Sets the minimum width of the layout.
311 * It is not guaranteed the layout will be able to achieve this minimum width (for example, if its parent
312 * layout constrains it with less available width).
314 * @param[in] minWidth The minimum width the layout will try to be, in pixels
316 * @see #GetMinimumWidth()
318 void SetMinimumWidth( LayoutLength minWidth );
321 * @brief Sets the minimum height of the layout.
323 * It is not guaranteed the layout will be able to achieve this minimum height (for example, if its parent
324 * layout constrains it with less available height).
326 * @param[in] minHeight The minimum height the layout will try to be, in pixels
328 * @see #GetMinimumHeight()
330 void SetMinimumHeight( LayoutLength minHeight );
333 * @brief Returns the minimum width of the layout.
335 * @return the minimum width the layout will try to be, in pixels
337 * @see #SetMinimumWidth(LayoutLength)
339 LayoutLength GetMinimumWidth() const;
342 * @brief Returns the minimum height of the layout.
344 * @return the minimum height the layout will try to be, in pixels
346 * @see #SetMinimumHeight(LayoutLength)
348 LayoutLength GetMinimumHeight() const;
351 * Get the padding information.
352 * @return The padding information
354 Extents GetPadding() const;
357 * Get the margin information.
358 * @return The margin information
360 Extents GetMargin() const;
364 * @brief Allow directly deriving classes to remove layout children when unparented
366 virtual void OnUnparent(){};
369 * @brief Ensure direct derived types register their child properties with the owner
371 * @param[in] containerType The type name of the owner container
373 virtual void OnRegisterChildProperties( const std::string& containerType );
376 * @brief Measure the layout and its content to determine the measured width and the
379 * This method is invoked by {@link #Measure(MeasureSpec, MeasureSpec)} and
380 * should be overridden by subclasses to provide accurate and efficient
381 * measurement of their contents.
383 * <strong>CONTRACT:</strong> When overriding this method, you
384 * <em>must</em> call {@link #SetMeasuredDimensions(MeasuredSize,MeasuredSize)} to store the
385 * measured width and height of this layout. Failure to do so will trigger an
386 * <code>IllegalStateException</code>, thrown by
387 * {@link #Measure(MeasureSpec,MeasureSpec)}. Calling the superclass'
388 * {@link #OnMeasure(MeasureSpec,MeasureSpec)} is a valid use.
390 * The base class implementation of measure defaults to the background size,
391 * unless a larger size is allowed by the MeasureSpec. Subclasses should
392 * override {@link #OnMeasure(MeasureSpec,MeasureSpec)} to provide better measurements of
395 * If this method is overridden, it is the subclass's responsibility to make
396 * sure the measured height and width are at least the layout's minimum height
397 * and width ({@link #GetSuggestedMinimumHeight()} and
398 * {@link #GetSuggestedMinimumWidth()}).
400 * @param[in] widthMeasureSpec horizontal space requirements as imposed by the parent.
401 * The requirements are encoded with
402 * {@link MeasureSpec}.
403 * @param[in] heightMeasureSpec vertical space requirements as imposed by the parent.
404 * The requirements are encoded with
405 * {@link MeasureSpec}.
407 * @see #GetMeasuredWidth()
408 * @see #GetMeasuredHeight()
409 * @see #GetSuggestedMinimumHeight()
410 * @see #GetSuggestedMinimumWidth()
411 * @see MeasureSpec#GetMode(int)
412 * @see MeasureSpec#GetSize(int)
414 virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec );
417 * @brief Called from Layout() when this layout should assign a size and position to each of its children.
419 * Derived classes with children should override this method and call Layout() on each of their children.
421 * @param[in] changed This is a new size or position for this layout
422 * @param[in] left Left position, relative to parent
423 * @param[in] top Top position, relative to parent
424 * @param[in] right Right position, relative to parent
425 * @param[in] bottom Bottom position, relative to parent
427 virtual void OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom );
431 * @brief This method must be called by {@link #OnMeasure(MeasureSpec,MeasureSpec)} to store the
432 * measured width and measured height.
434 * Failing to do so will trigger an exception at measurement time.
436 * @param[in] measuredWidth The measured width of this layout. This may have a state of
437 * {@link MeasuredSize::MEASURED_SIZE_TOO_SMALL}
439 * @param[in] measuredHeight The measured height of this layout. This may have a state of
440 * {@link MeasuredSize::MEASURED_SIZE_TOO_SMALL}
442 void SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight );
445 * @brief Utility to reconcile a desired size and state, with constraints imposed by a MeasureSpec.
447 * @param[in] size How big the layout wants to be.
448 * @param[in] measureSpec Constraints imposed by the parent.
449 * @param[in] childMeasuredState Size information bit mask for the layout's children.
451 * @return A measured size, which may indicate that it is too small.
453 static MeasuredSize ResolveSizeAndState( LayoutLength size, MeasureSpec measureSpec,
454 MeasuredSize::State childMeasuredState );
457 * @brief Sets the frame (the size and position) of the layout onto it's owner.
458 * Collect all properties to animate after the layout update.
460 * @param[in] left The horizontal position of the left edge of this frame within the parent layout
461 * @param[in] top The vertical position of the top edge of this frame within the parent layout
462 * @param[in] right The horizontal position of the right edge of this frame within the parent layout
463 * @param[in] bottom The vertical position of the bottom edge of this frame within the parent layout
465 bool SetFrame( LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom );
468 * Virtual method to inform derived classes when the layout size changed
469 * @param[in] newSize The new size of the layout
470 * @param[in] oldSize The old size of the layout
472 virtual void OnSizeChanged( LayoutSize newSize, LayoutSize oldSize );
476 * @brief Initialization method for LayoutGroup to override
478 virtual void OnInitialize();
481 * @brief Called when a layer animation state is changed.
483 virtual void OnAnimationStateChanged( bool animateLayout ) {}
487 * @brief Called to change the size of the layout.
489 * @param[in] newSize The new size of the layout
490 * @param[in] oldSize The old size of the layout
492 void SizeChange( LayoutSize newSize, LayoutSize oldSize );
495 * @brief Triggered when a layout animation finished.
497 * @param[in] animation A handle to the layout animation
499 void OnLayoutAnimationFinished( Animation& animation );
502 * @brief Register child properties of layout with owner type.
504 * The Actor hierarchy uses these registered properties in the type
505 * system to ensure child custom properties are properly initialized.
507 * @param[in] containerType The type of the containing view (owner)
509 void RegisterChildProperties( const std::string& containerType );
512 class Impl; // Class declaration is public so we can add devel API's in the future
515 std::unique_ptr<Impl> mImpl; ///< Implementation class holds all the data
516 SlotDelegate<LayoutItem> mSlotDelegate;
519 } //namespace Internal
521 inline Internal::LayoutItem& GetImplementation( Dali::Toolkit::LayoutItem& handle )
523 DALI_ASSERT_ALWAYS( handle && "LayoutItem handle is empty" );
524 BaseObject& object = handle.GetBaseObject();
525 return static_cast< Internal::LayoutItem& >( object );
528 inline const Internal::LayoutItem& GetImplementation( const Dali::Toolkit::LayoutItem& handle )
530 DALI_ASSERT_ALWAYS( handle && "LayoutItem handle is empty" );
531 const BaseObject& object = handle.GetBaseObject();
532 return static_cast< const Internal::LayoutItem& >( object );
535 } //namespace Toolkit
538 #endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_LAYOUT_ITEM_H