40c49118d2386a86563496ae0c49490fdc3b53c7
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-relayouter.h
1 #ifndef DALI_INTERNAL_ACTOR_RELAYOUTER_H
2 #define DALI_INTERNAL_ACTOR_RELAYOUTER_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/event/actors/actor-impl.h>
23 #include <dali/public-api/math/vector2.h>
24 #include <dali/public-api/math/vector3.h>
25
26 namespace Dali
27 {
28 namespace Internal
29 {
30 /**
31  * Struct to do some actor specific relayouting and store related variables
32  */
33 struct Actor::Relayouter
34 {
35   // Defaults
36   static constexpr Vector3               DEFAULT_SIZE_MODE_FACTOR{1.0f, 1.0f, 1.0f};
37   static constexpr Vector2               DEFAULT_PREFERRED_SIZE{0.0f, 0.0f};
38   static constexpr Vector2               DEFAULT_DIMENSION_PADDING{0.0f, 0.0f};
39   static constexpr SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
40
41   /// Constructor
42   Relayouter();
43
44   /// Default Destructor
45   ~Relayouter() = default;
46
47   /// @copydoc Actor::GetResizePolicy
48   ResizePolicy::Type GetResizePolicy(Dimension::Type dimension) const;
49
50   /// @copydoc Actor::SetPadding
51   void SetPadding(const Vector2& padding, Dimension::Type dimension);
52
53   /// @copydoc Actor::GetPadding
54   Vector2 GetPadding(Dimension::Type dimension);
55
56   /// @copydoc Actor::SetLayoutNegotiated
57   void SetLayoutNegotiated(bool negotiated, Dimension::Type dimension);
58
59   /// @copydoc Actor::IsLayoutNegotiated
60   bool IsLayoutNegotiated(Dimension::Type dimension) const;
61
62   /// @copydoc Actor::ApplySizeSetPolicy
63   Vector2 ApplySizeSetPolicy(Internal::Actor& actor, const Vector2& size);
64
65   /// @copydoc Actor::SetUseAssignedSize
66   void SetUseAssignedSize(bool use, Dimension::Type dimension);
67
68   /// @copydoc Actor::GetUseAssignedSize
69   bool GetUseAssignedSize(Dimension::Type dimension) const;
70
71   /// @copydoc Actor::SetMinimumSize
72   void SetMinimumSize(float size, Dimension::Type dimension);
73
74   /// @copydoc Actor::GetMinimumSize
75   float GetMinimumSize(Dimension::Type dimension) const;
76
77   /// @copydoc Actor::SetMaximumSize
78   void SetMaximumSize(float size, Dimension::Type dimension);
79
80   /// @copydoc Actor::GetMaximumSize
81   float GetMaximumSize(Dimension::Type dimension) const;
82
83   /// @copydoc Actor::SetResizePolicy
84   void SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension, Vector3& targetSize);
85
86   /// @copydoc Actor::GetRelayoutDependentOnParent
87   bool GetRelayoutDependentOnParent(Dimension::Type dimension);
88
89   /// @copydoc Actor::GetRelayoutDependentOnChildren
90   bool GetRelayoutDependentOnChildren(Dimension::Type dimension);
91
92   /// @copydoc Actor::GetRelayoutDependentOnDimension
93   bool GetRelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependency);
94
95   /// @copydoc Actor::SetDimensionDependency
96   void SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency);
97
98   /// @copydoc Actor::GetDimensionDependency
99   Dimension::Type GetDimensionDependency(Dimension::Type dimension) const;
100
101   /// @copydoc Actor::SetLayoutDirty
102   void SetLayoutDirty(bool dirty, Dimension::Type dimension);
103
104   /// @copydoc Actor::IsLayoutDirty
105   bool IsLayoutDirty(Dimension::Type dimension) const;
106
107   /// @copydoc Actor::SetPreferredSize
108   /// @actor[in] actor The Actor whose preferred size we wish to set
109   void SetPreferredSize(Actor& actor, const Vector2& size);
110
111   /**
112    * @brief Clamp a dimension given the relayout constraints on given actor
113    *
114    * @param[in] actor The actor to clamp
115    * @param[in] size The size to constrain
116    * @param[in] dimension The dimension the size exists in
117    * @return Return the clamped size
118    */
119   static float ClampDimension(const Internal::Actor& actor, float size, Dimension::Type dimension);
120
121   /// @copydoc Actor::SetNegotiatedDimension
122   void SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension);
123
124   /// @copydoc Actor::GetNegotiatedDimension
125   float GetNegotiatedDimension(Dimension::Type dimension);
126
127   /**
128    * Negotiate a dimension based on the size of the parent
129    *
130    * @param[in] dimension The dimension to negotiate on
131    * @return Return the negotiated size
132    */
133   static float NegotiateDimensionFromParent(Actor& actor, Dimension::Type dimension);
134
135   /**
136    * @brief Negotiate a dimension based on the size of the children
137    *
138    * @param[in] dimension The dimension to negotiate on
139    * @return Return the negotiated size
140    */
141   static float NegotiateDimensionFromChildren(Actor& actor, Dimension::Type dimension);
142
143   /**
144    * Negotiate size for a specific dimension
145    *
146    * The algorithm adopts a recursive dependency checking approach. Meaning, that wherever dependencies
147    * are found, e.g. an actor dependent on its parent, the dependency will be calculated first with NegotiatedDimension and
148    * LayoutDimensionNegotiated flags being filled in on the actor.
149    *
150    * @post All actors that exist in the dependency chain connected to the given actor will have had their NegotiatedDimensions
151    * calculated and set as well as the LayoutDimensionNegotiated flags.
152    *
153    * @param[in] actor The actor whose dimension we are negotiating
154    * @param[in] dimension The dimension to negotiate on
155    * @param[in] allocatedSize The size constraint that the actor must respect
156    */
157   static void NegotiateDimension(Actor& actor, Dimension::Type dimension, const Vector2& allocatedSize, Actor::ActorDimensionStack& recursionStack);
158
159   /**
160    * Negotiate sizes for a control in all dimensions
161    *
162    * @param[in] actor The actor whose dimensions we are negotiating
163    * @param[in] allocatedSize The size constraint that the control must respect
164    */
165   static void NegotiateDimensions(Actor& actor, const Vector2& allocatedSize);
166
167   /**
168    * @brief Called by the RelayoutController to negotiate the size of an actor.
169    *
170    * The size allocated by the the algorithm is passed in which the
171    * actor must adhere to.  A container is passed in as well which
172    * the actor should populate with actors it has not / or does not
173    * need to handle in its size negotiation.
174    *
175    * @param[in] actor The actor whose size we are negotiating
176    * @param[in]      size       The allocated size.
177    * @param[in,out]  container  The container that holds actors that are fed back into the
178    *                            RelayoutController algorithm.
179    */
180   static void NegotiateSize(Actor& actor, const Vector2& allocatedSize, RelayoutContainer& container);
181
182   /**
183    * Get the value for the given dimension
184    *
185    * @param[in] values The vector to get values from
186    * @param[in] dimension The dimension to fetch
187    * @return the value of the given dimension
188    */
189   static float GetDimensionValue(const Vector3& values, const Dimension::Type dimension);
190
191   /// @copydoc Actor::CalculateSize
192   static float CalculateSize(Actor& actor, Dimension::Type dimension, const Vector2& maximumSize);
193
194   /// @copydoc Actor::CalculateChildSizeBase
195   static float CalculateChildSize(Actor& actor, const Actor& child, Dimension::Type dimension);
196
197 public:
198   ResizePolicy::Type resizePolicies[Dimension::DIMENSION_COUNT];  ///< Resize policies
199   bool               useAssignedSize[Dimension::DIMENSION_COUNT]; ///< The flag to specify whether the size should be assigned to the actor
200
201   Dimension::Type dimensionDependencies[Dimension::DIMENSION_COUNT]; ///< A list of dimension dependencies
202
203   Vector2 dimensionPadding[Dimension::DIMENSION_COUNT]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
204
205   float negotiatedDimensions[Dimension::DIMENSION_COUNT]; ///< Storage for when a dimension is negotiated but before set on actor
206
207   float minimumSize[Dimension::DIMENSION_COUNT]; ///< The minimum size an actor can be
208   float maximumSize[Dimension::DIMENSION_COUNT]; ///< The maximum size an actor can be
209
210   bool dimensionNegotiated[Dimension::DIMENSION_COUNT]; ///< Has the dimension been negotiated
211   bool dimensionDirty[Dimension::DIMENSION_COUNT];      ///< Flags indicating whether the layout dimension is dirty or not
212
213   Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes
214
215   Vector2 preferredSize; ///< The preferred size of the actor
216
217   SizeScalePolicy::Type sizeSetPolicy : 3; ///< Policy to apply when setting size. Enough room for the enum
218
219   bool relayoutEnabled : 1;   ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
220   bool insideRelayout : 1;    ///< Locking flag to prevent recursive relayouts on size set
221   bool relayoutRequested : 1; ///< Whether the relayout is requested.
222 };
223
224 } // namespace Internal
225
226 } // namespace Dali
227
228 #endif // DALI_INTERNAL_ACTOR_RELAYOUTER_H